分布式缓存
单点 Redis 的问题及解决
- 数据丢失:实现Redis数据持久化
- 并发能力:搭建主从集群,实现读写分离
- 存储能力:搭建分片集群,利用插槽机制实现动态扩容
- 故障恢复能力:利用哨兵机制,实现健康检测和自动恢复
RDB
RDB全称Redis Database Backup file (Redis数据备份文件),也被叫做Redis数据快照,简单来说就是把内存中的所有数据都记录到磁盘上,当Redis实时故障重启后,从磁盘读取快照文件,恢复数据
save #由Redis主进程来执行RDB,会阻塞所有命令
bgsave #开启子进程执行RDB,避免主进程收到影响,推荐
RDB默认是开启的,内部有触发机制,可以在redis.conf
文件中找到,RDB文件也支持压缩;Redis关闭时,也会触发一次RDB
RDB方式bgsave的基本流程
- fork主进程得到一个子进程,共享内存空间
- 子进程读取内存数据并写入新的RDB文件
- 用新的RDB文件替换旧的RDB文件
RDB会在什么时候执行?save 60 1000的含义?
- 默认时停止服务的时候
- 代表60s内至少执行1000次修改才会触发RDB
RDB的缺点
- RDB执行间隔时间长,两次RDB之间的写入数据由丢失的风险
- fork子进程、压缩、写RDB文件比较耗时
AOF
AOF全称Append Only Field(追加文件)。Redis处理的每一个写命令都会记录在AOF文件。可以看做时命令日志文件。
AOF默认是关闭的,AOF的命令记录频率也可以通过修改redis.conf
文件修改
# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always
# 写命令执行完先放到AOF缓冲区,然后表示每隔1s将缓冲区数据写入到AOF文件,是默认方案
appendfsync everysec
# 写入命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写到磁盘
appendfsync no
-
因为AOF记录的是每次写的命令。AOF文件会比RDB文件大,而且AOF中会记录对同一个key的多次写操作,但是只有最后一次的才有意义,通过执行
bgreWriteaop
命令,可以让AOF文件执行重写功能,用最少得命令达到相同的效果 -
Redis也会在触发阈值时自动去重写AOF文件,阈值也可以在
redis.conf
中配置# AOF文件比上次文件增长超过多少百分比触发重写 auto-aof-reWrite-percentage 100 # AOF文件体积最小多大以上才触发重写 auto-aof-rewrite-min-size 64mb
-
AOF和RDB同时开启,会以AOF优先;在实际的开发中往往结合两者使用
Redis主从
单点的Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离;
主从数据同步原理
第一次是全量同步
全量同步的流程
- slave节点请求增量同步
- master节点判断replid,发现不一致,拒绝增量同步
- master将完整的内存数据生成RDB文件,发送RDB到slave
- slave清空本地数据,加载master的RDB文件
- master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
如果slave重启后,执行增量同步
哨兵(Sentinel)
Redis提供哨兵(Sentinel)机制来实现主从集群的自动恢复
- 监控:哨兵会不断监控master和slave的健康状况
- 故障自动恢复:当master故障时,Sentinel哨兵会将其中一个slave提升为master,当老master恢复后,还是以新的master为主
- 通知:哨兵充当Redis客户端发现来源,当集群发生故障转移时,会将最新的消息推送给Redis的客户端
哨兵基于心跳监测机制,每个1s向集群的每一个实例发送ping命令:
- 主观下线:如果某个哨兵节点发现某实例为在规定时间内响应,则认为该实例主观下线
- 客观下线:若超过指定数量(quorum)的哨兵都认为该实例主观下线,则该实例客观下线,类似投票机制
选举新的master
- 首先会判断slave节点与master节点断开时间的长短,如果超过指定值,则会排除在外
- 然后根据slave节点的slave-priority,越小优先级越高
- slave一样,则判断slave节点的offset值。越大说明数据越新,优先级越高
- 最后判断slave节点的运行id大小,越小优先级越高
故障转移
- Sentinel哨兵给备选的slave发送命令,让该节点称为新的master
- 哨兵给所有的其它slave发送命令,让这些节点成为新master的slave节点,开始从master同步数据
- 最后,哨兵将故障节点,也就是老的master标记为slave从节点
Redis分片集群
主从和哨兵解决了高可用、高并发读的问题,但依然有两个问题没有解决:文章来源:https://www.toymoban.com/news/detail-499831.html
- 海量数据存储问题
- 高并发写的问题
使用分片集群可以解决以上问题文章来源地址https://www.toymoban.com/news/detail-499831.html
- 集群中有多个master,每个master保存不同的数据
- 每个master都可以有多个slave节点
- master之间通过ping监测彼此健康状态
- 客户端请求可以访问集群中的任一个节点,最终都会被转发到正确的节点上
散列插槽
- Redis会把每个master节点映射到0~16383共16384个插槽(Hash slot)上
- 数据key不是与节点绑定,而是与插槽绑定,Redis会根据key的有效部分计算插槽值,分为两种情况:
- key中包含"{}“,且”{}“中至少包含一个字符,”{}"中的部分是有效部分,这就实现了控制不同的key在同一插槽上
- 可以中不包含"{}",整个可以都是有效部分
- 计算方式是利用CRC16算法得到一个Hash值,然后对16384取余,得到的就是slot值
到了这里,关于Redis 分布式缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!