Redis
Redis
Redis(Remote Dictionary Server) : 是一款用C语言开发的高性能键值对数据库
-
Nosql (非关系型)
Redis是一款Nosql数据库
Redis的value 5种数据类型
Redis的key是string类型
数据类型 | 数据结构 |
---|---|
string | 字符串 |
list | 双向链表 |
set | HashSet 不可重复 |
hash | HashMap |
sorted_set | 不可重复.可排序的set |
string 类型
-
添加/修改
set key value
case: set zhangsan 20
-
删除
del key
case: del zhangsan
-
查询
get key
case: get zhangsan
-
对key自增一
incr key
-
对key增加指定的数值
incrby key number
-
对key自减一
decr key
-
减去指定数值
decrby key
-
添加数据并且指定存活时间
setex key ttl value
-
有值不操作, 没有则添加数据
setnx key value
Redis中所有的操作都是原子性的, 因为Redis采用单线程处理所有任务,所以不存在线程安全问题
Hash 类型
增加/修改数据: hset key field value
删除数据: hdel key field
获取所有数据: hgetall key
获取数据: hget key field
添加多条数据: hmset key field value field value ....
获取key对应的field数量 hlen key
有值则不操作,没有值则添加数据: hsetnx key field value;
获取所有的field: hkeys key
list 类型
头部添加 lpush key value
尾部添加 rpush key value
从头部获取数据并删除 lpop key
从尾部获取数据并删除 lpop key
获取所有数据 lrange key 0 -1
获取key中元素数量 llen key
set 类型
添加数据 sadd key value
删除数据 srem key value
获取全部数据 smembers key
判断数据是否在集合中 sismember key value
sorted_set类型
添加数据 zadd key score value
删除数据 zrem key value
获取全部数据并显示socre值[升序] zrange key 0 -1 withscores
获取全部数据并显示scoree值[降序] zrevrange key 0 -1 withscores;
增加score值 zincrby key number value
获取score值 zscore key value
通用命令
删除指定key del key
判断key是否存在 exists key
获取key的类型 type key
为指定key设置有效时间 expires key time
获取key的有效时间 ttl key
将key设置为永久性的 persist key
keys pattern 根据规则获取key
Redis数据库操作
切换数据库 select index
退出 quit
测试连接 ping
将当前数据库清空 flushdb
将所有数据库清空 flushall
查看当前数据库有多少个key dbsize
Redis的单线程与高性能
-
Redis为什么这么快?
因为Redis的所有数据都是在内存中,所有的运算都是内存级别的运算,而且Redis采用单线程工作,避免了多线程的切换性能损耗问题
Redis的持久化
在Redis中有两种持久化方式 分别是 RDB 和 AOF
RDB快照
- 在默认情况下, Redis将内存中的数据以快照的方式保存在名字为dump.rdb的二进制文件中
RDB采用的命令是bgsave指令, 此指令会将内存中的数据在后台以快照形式保存在rdb二进制文件中
可以在redis.conf文件中对RDB持久化方式进行配置
AOF
- 以日志的方式记录每一次修改数据的命令到aof文件中,当redis重启时执行aof文件中的命令即可达到恢复数据的目的
在redis.conf 文件中开启此功能
appendonly yes
AOF 写数据三种策略
- always (每次): 每次修改数据的指令都会持久化到aof文件中,数据零误差,但效率低
- everysec(每秒): 每秒将缓冲区的指令持久化到aof文件中,数据准确性高, 最多丢失一秒数据
- no(系统控制): 由操作系统每次同步到aof文件的周期
AOF重写(bgrewriteaof)
AOF文件重写就是将对同一个数据的多个操作执行的结果转换为最终结果数据对应的指令进行记录
AOF重写作用
① 节省磁盘空间 ② 提高持久化效率,降低持久化写的时间 ③ 提高数据恢复时的效率
AOF重写规则
① 已过期的数据不再写入文件
② 忽略无效指令
③ 对同一条数据的多个写命令合并为一个命令
RDB 与 AOF 的对比
RDB持久化方式以内存快照的形式保存,非常便于进行数据的恢复,但是可能会丢失一定的数据
AOF持久化方式当配置为everysec的策略时,只会丢失一秒的数据,数据准确性高,但是当redis进行数据恢复时,AOF持久化恢复数据要比RDB慢很多
Redis 4.0 混合持久化
重启Redis时, 我们很少使用RDB来恢复数据, 因为可能会丢失大量数据,所以通常采用AOF日志重放,但是重放AOF日志性能要比RDB慢的多, 当数据量很大时,启动需要花费很长时间来恢复数据, 所以Redis 4.0解决这个问题所带来一个新的持久化方案: 混合持久化
-
混合持久化
AOF在重写AOF文件时, 将重写这一刻之前的内存rdb快照文件的内容和增量的AOF修改数据的命令,都写到新的aof文件中,当重写完成后就进行改名,覆盖之前的aof文件,完成新旧两个aof文件的替换
开启混合持久化:
aof-use-rdb-preamble yes
混合持久化文件结构为: 头部rdb格式 尾部aof格式
缓存淘汰策略
当Redis内存超出物理内存限制时,内存的数据就会开始和磁盘频繁的交换(虚拟内存),交换会让Redis的性能急剧下降,为了限制最大使用内存, Redis提供了配置参数maxmemory来限制内存最大大小, 当Redis使用的内存超出maxmemory时,Redis提供了8种缓存淘汰策略,可以让用户决定如何腾出空间以继续提供写服务
- noeviction 禁止写请求 。读, 写请求可以进行, 不会丢失数据,但会印象业务 (默认策略)
- volatile-lru 淘汰设置了过期时间的最近最少使用的Key
- volatile-ttl 淘汰设置了过期时间的key, ttl越小的优先淘汰
- volatile-random 随机淘汰设置了过期时间的key
- volatile-lfu 淘汰最少使用的设置了过期时间的key
- allkeys-lru 淘汰最近最少使用的key
- allkeys-lfu 淘汰最少使用的
- allkeys-random 随机淘汰
过期数据删除策略
- 定时删除: 当key到了过期时间立即删除 ( 影响性能)
- 定期删除: 每隔一段时间删除已经过期的key
- 惰性删除: 当访问已经过期的key时才删除
Redis集群方案
主从复制(读写分离)
主从复制就是将master中的数据即使,有效的复制到slave中,一个master可以拥有多个slave, 一个slave只能对应一个master
职责:
master: 写数据,执行写操作时,将出现的数据自动的同步到slave上
slave: 读数据
作用:
读写分离, master写, slave读
数据冗余,实现数据的备份
高可用的基石, 哨兵模式,集群模式都是基于主从复制的
缺点:
当master挂掉之后,整个集群就无法提供写的功能,没有自动的故障转移机制
配置方式
在slave节点的redis.conf配置: slave masterIp:port
哨兵模式(Sentinel)
哨兵(sentinel) 是一个分布式系统,用于对主从结构的每台服务器进行监控, 当出现故障时,通过投票机制选取新的master,并将所有的slave连接到新的master
哨兵作用:
监控: 不断的检查master和slave是否正常运行
通知: 当被监控的服务实例出现问题时,向其他哨兵发送通知
自动故障转移: 当master出现故障时,断开master与slave的连接,选取一个新的slave作为master,并将其他的s lave连接到新的master
选择master的指标
先剔除不在线的,响应慢的,与原master断开时间短的
优先选优先级高的, offset大的(数据是最新的), runid最小的
哨兵的自动故障转移机制大概思路
当哨兵检测到master出现故暂后,首先将master的状态设为假死状态,然后通知其他的哨兵,其他的哨兵也会检测master的状态,当确定master挂掉的哨兵数量符合我们配置的数量时,此时哨兵集群就会选取一个哨兵leader,
哨兵leader负责将master的状态修改为下线状态,然后根据规则选取一个slave作为master,再通知其他的slave断开与原master的连接,将所有的slave连接到新的master
集群模式(cluster)
Redis集群模式是由多个主从节点群所组的服务集群,它具有高可用,数据分片的特性
Redis不需要sentinel哨兵也可以完成自动故障转移, 并且Redis集群模式可以水平扩展,最多可以扩展16384个节点
-
Redis高可用集群搭建
修改redis.conf
cluster-enabled yes # 启用集群模式 cluster-config-file-nodes-ip或者端口号.conf 集群节点信息文件 cluster-time-out 5000 # 节点过期时间 protected no # 关闭保护模式 appendonly yes # aof持久化 aof-use-rdb-preamble yes # 混合持久化 requirepass 密码 # redis访问密码 clusterauth 密码 # 集群密码
使用redis-cli 创建整个集群
redis-cli -a 集群密码 --cluster create --cluster replicas slave数量 节点1ip:port 节点2ip:port 节点3ip:port ...
连接集群
redis-cli -a 集群密码 -c -h ip -p port
添加新的节点
redis-cli -a 集群密码 --cluster add-node 新节点ip:port 已存在节点的ip:port
删除节点
redis-cli -a 集群密码 --cluster del-node 已经存在节点的ip:port 要删除节点的runid
分配hash槽
redis-cli -a 集群密码 --cluster reshard 已经存在节点的ip:port [ 接下来按提示分配
Redis集群概念
Redis集群模式将所有的数据分为16384个槽, 每一个节点负责其中的一部分槽位,槽位的信息存储于集群中每一个节点上
当Redis Cluster的客户端来连接集群时,也会得到一份集群的槽位配置信息并将其缓存在客户端本地,当需要找到某个Key时,可以直接定位到目标节点,如果槽位信息发生变化, 就会重定向到真正的目标节点上
槽位定位算法
Cluster 默认会对所有的key值使用CRC16算法再进行hash得到一个整数,再用这个整数对16384进行取模来得到具体槽位
跳转重定向
当客户端向一个节点发出了指令,该节点根据槽位定位算法发现指令的Key的槽位并不在当前节点上,这时它就会向客户端发送一个跳转指令并携带节点地址,告诉客户端去链接这个节点去进行操作,并且客户端还会同步更新本地的槽位映射表缓存
Redis 名字介绍
缓存预热
缓存预热就是在系统启动前,提前将相关的缓存数据直接加载到缓存系统中,避免在用户请求时,先查询数据库,然后再将数据缓存的问题,用户直接查询事先就被缓存好的数据
缓存雪崩
缓存雪崩就是瞬间过期的数据量太大,导致对数据库服务器造成压力
解决方案:
在原有的过期时间上随机再加一定的时间作为过期时间,避免大量的key在同一时间过期
缓存击穿
缓存击穿就是单个高热(访问量高的)数据过期的瞬间, 数据访问量大,未命中缓存(redis), 发起了大量对同一数据的数据库访问,导致对数据库服务造成压力
解决方案:
将高热数据的key设置为永久有效
缓存穿透
缓存穿透就是访问了缓存和数据库中都不存在的数据,需要每次访问数据库,导致对数据库服务器造成压力
解决方案:
对于找不到数据的key, 进行一定时间的缓存,避免重复访问数据库