redis主从架构
主负责写,从负责读
redis replication
redis主从架构-》读写分离架构-》可支持水平扩展的度高并发架构
1.redis采用异步的方式复制数据到slave节点,redis 2.8开始slave node会周期性的确认自己每次复制的数据量
2.slave节点用旧的数据集提供查询服务,等数据复制好了,加载新数据集,这个时候会停止服务
3.master节点必须开启rdb和aof持久化,因为不开启数据丢了,master节点会认为本来就没有数据,然后去同步slave节点,导致slave节点数据丢失
1.复制过程核心原理
slave节点第一次连接master节点,主节点会开启一个后台线程,复制一份rdb快照文件给从节点,同时缓存主节点的写请求在内存中,然后从节点接收rdb快照文件先写入磁盘,然后加载到内存中。然后master节点会吧内存中的写请求也同步给slave节点。
slave节点不是第一次连接master节点,仅仅复制给slave节点缺少的部分。
2.主从复制的断点续传
redis2.8开始,支持断点续传,如果主从复制过程中,网络断了,可以接着上次复制的offset继续复制
master 会在内存中创建一个backlog,主从都会保存一个replica offset和一个masetid。没有找到就执行全量复制
3.无磁盘化复制
master在内存中直接创建rdb,然后发送给salve,不会在自己本地落地磁盘
repl-diskless-sync no 要落地磁盘为yes
repl-diskless-sync-delay 5,等待一定时长再开始复制,因为要等更多slave重新连接过来
4,过期key处理
slave不会过期key,只会等待master过期key。如果master过期一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发给slave。
redis中保存一个run id ,如果主节点变了,就全量复制数据
redis复制的时候如果超过60秒会认为失败。repl-timeout 参数设置
主备切换
主redis挂了,切换从redis为主
sentinel哨兵
哨兵集群必须部署2个以上节点,因为部署两个节点的话,根据2/2+1需要两个节点同意才能通过,3个节点3/2+1要两个节点同意就能通过,为什么不建议部署4个简单?因为4/2+1=3 ,5/2+1=3。4个节点和5个节点都是需要3台机器同意,5个节点可以允许挂掉两台机器。
数据丢失的情况
1.写磁盘的时候,命令还没刷到磁盘上
2.主从复制的时候,如果主服务器在接收到请求,还没同步到从服务器的时候挂了,数据丢失
3.脑裂问题,出现网络分区,列如:主节点和客户端在一起,从节点和哨兵集群在一起,然后哨兵集群新选举了一个主节点,这个时候客户端一只在往旧的主节点上写数据,当旧的节点连上时,会被新的主节点同步数据,这个时候数据丢失。
解决数据丢失 主从和脑裂问题:
min-slaves-to-write 1 几个slave
min-slaves-max-lag 10 数据同步延时的时间
要求至少有1个slave,数据复制和同步的延迟不能超过10秒
异步复制数据,一旦slave的ack延时太长,就认为复制给从节点的数据太多了,就拒绝请求,这样如果主节点宕机的损失数据范围就被控制住了,客户端被拒绝后需要存如消息队列,让消息队列来重试。
shown和odown转换机制
sdown和odown两种失败状态
sdown是主观宕机,就是自己觉得一个master挂机了
odown是客观宕机,quorum数量的哨兵都觉得一个master宕机了
哨兵互相之间的发现,是通过redis的pub/sub系统实现的,每个哨兵都会往sentinel:hello这个channel里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他哨兵的存在。
master宕机slave节点的配置由哨兵自动更改为新的master,更新配置根据版本号来。
redis cluster
在redis cluster集群下,每个redis要开放两个端口,比如6379 和 16379 ,6378和16378
redis用15379来进行通信,类似集群总线,cluster bus的东西
redis cluster的hash slot算法
redis cluster有固定的16384个hash slot,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot
redis cluster中每个master都会持有部分slot,比如有3个master,那么可能每个master持有5000多个hash slot
hash slot让node的增加和移除很简单,增加一个master,就将其他master的hash slot 移动部分过去,减少一个master,就将它的hash slot移动到其他master上去
移动 hash slot的成本非常低的
客户端的API,可以对指定的数据,让他们走同一个hash slot,通过hash tag来实现
runid:每个redis节点启动都会生成一个唯一的uuid,每次redis重启后,runid都会发生变化
offset:主节点和从节点都有自己的offset保存数据的长度,从节点收到主节点命令后,会把自己的offset给主节点,主节点保存从节点的offset,然后判断需要给从节点多少数据。
repl_backlog_size:保存在主节点上的一个固定长度的先进先出队列,默认大小是1MB.
全量复制:
从节点发送psync命令,psyns runid offset(由于是第一次,runid为?,offset为-1)
主节点返回fullresync runid offset,runid是主节点的runid,offset是主节点目前的offset。从节点保存信息
主节点启动bgsave命令fork子进程进行RDB持久化,持久化的时候写数据会复制一份副本,修改数据在副本上进行,原来的数据继续复制,复制完成后,把原来的数据覆盖。
从节点清理本地数据并加载RDB,如果开启了AOF会重写AOF
部分复制:
复制偏移量:psync runid offset
复制积压缓冲区:当主节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制
如果从节点保存的runid与主节点现在的runid相同,说明从节点之前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况);
如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的redis节点并不是当前的主节点,只能进行全量复制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下