Redis主从同步机制详解

背景:
我们知道,当有多台 Redis 服务器时,肯定就有一台主服务器和多台从服务器。一般来说,主服务器进行写操作,从服务器进行读操作。
那么这里有存在一个问题:从服务器如何和主服务器进行数据同步的呢?
这个问题,就是通过今天的内容:主从同步机制。
读写分离
在redis主从架构中,Master节点负责处理写请求,Slave节点只处理读请求。对于写请求少,读请求多的场景,例如电商详情页,通过这种读写分离的操作可以大幅提高并发量,通过增加redis从节点的数量可以使得redis的QPS达到10W+
在这里插入图片描述
主从同步:
Master节点接收到写请求并处理后,需要告知Slave节点数据发生了改变,保持主从节点数据一致的行为称为主从同步。
主从同步的方法
(1)增量同步
redis 同步的是指令流,主节点会将那些对自己的状态产生修改性影响的指令记录在本地的内存 buffer 中,然后异步将 buffer 中的指令同步到从节点,从节点一边执行同步的指令流来达到和主节点一样的状态,一边向主节点反馈自己同步到哪里了 (偏移量,这是redis-2.8之后才有的特性)。从节点同步数据的时候不会影响主节点的正常工作,也不会影响自己对外提供读服务的功能,从节点会用旧的数据来提供服务,当同步完成后,需要删除旧数据集,加载新数据,这个时候才会暂停对外服务。
因为内存的 buffer 是有限的,所以 redis 主节点不能将所有的指令都记录在内存 buffer 中。redis 的复制内存 buffer 是一个定长的环形数组,如果数组内容满
了,就会从头开始覆盖前面的内容。
(2)快照同步
如果节点间网络通信不好,那么当从节点同步的速度不如主节点接收新写请求的速度时,buffer 中会丢失一部分指令,从节点中的数据将与主节点中的数据不一致,此时将会触发快照同步。
快照同步是一个非常耗费资源的操作,它首先需要在主节点上进行一次 bgsave 将当前内存的数据全部快照到RDB文件中,然后再将快照文件的内容全部传送到从节点。从节点将RDB文件接受完毕后,立即执行一次全量加载,加载之前先要将当前内存的数据清空。加载完毕后通知主节点继续进行增量同步。
在整个快照同步进行的过程中,主节点的复制 buffer 还在不停的往前移动,如果快照同步的时间过长或者复制 buffer 太小,都会导致同步期间的增量指令在复制 buffer 中被覆盖,这样就会导致快照同步完成后无法进行增量复制,然后会再次发起快照同步,如此极有可能会陷入快照同步的死循环。所以需要配置一个合适的复制 buffer 大小参数,避免快照复制的死循环。
主从同步的详细流程
(1) 在从节点的配置文件中的slaveof配置项中配置了主节点的IP和port后,从节点就知道自己要和那个主节点进行连接了。
(2) 从节点内部有个定时任务,会每秒检查自己要连接的主节点是否上线,如果发现了主节点上线,就跟主节点进行网络连接。注意,此时仅仅是取得连接,还没有进行主从数据同步。
(3) 从节点发送ping命令给主节点进行连接,如果设置了口令认证(主节点设置了requirepass),那么从节点必须发送正确的口令(masterauth)进行认证。
(4) 主从节点连接成功后,主从节点进行一次快照同步。事实上,是否进行快照同步需要判断主节点的run id,当从节点发现已经连接过某个run id的主节点,那么视此次连接为重新连接,就不会进行快照同步。相同IP和port的主节点每次重启服务都会生成一个新的run id,所以每次主节点重启服务都会进行一次快照同步,如果想重启主节点服务而不改变run id,使用redis-cli debug reload命令。
(5) 当开始进行快照同步后,主节点在本地生成一份rdb快照文件,并将这个rdb文件发送给从节点,如果复制时间超过60秒(配置项:repl-timeout),那么就会认为复制失败,如果数据量比较大,要适当调大这个参数的值。主从节点进行快照同步的时候,主节点会把接收到的新请求命令写在缓存 buffer 中,当快照同步完成后,再把 buffer 中的指令增量同步到从节点。如果在快照同步期间,内存缓冲区大小超过256MB,或者超过64MB的状态持续时间超过60s(配置项:client-output-buffer-limit slave 256MB 64MB 60),那么也会认为快照同步失败。
(6) 从节点接收到RDB文件之后,清空自己的旧数据,然后重新加载RDB到自己的内存中,在这个过程中基于旧的数据对外提供服务。如果主节点开启了AOF,那么在快照同步结束后会立即执行BGREWRITEAOF,重写AOF文件。
(7) 主节点维护了一个backlog文件,默认是1MB大小,主节点向从节点发送全量数据(RDB文件)时,也会同步往backlog中写,这样当发送全量数据这个过程意外中断后,从backlog文件中可以得知数据有哪些是发送成功了,哪些还没有发送,然后当主从节点再次连接后,从失败的地方开始增量同步。这里需要注意的是,当快照同步连接中断后,主从节点再次连接并非是第一次连接,所以进行增量同步,而不是继续进行快照同步。
(8) 快照同步完成后,主节点后续接收到写请求导致数据变化后,将和从节点进行增量同步,遇到 buffer 溢出则再触发快照同步。
(9) 主从节点都会维护一个offset,随着主节点的数据变化以及主从同步的进行,主从节点会不断累加自己维护的offset,从节点每秒都会上报自己的offset给主节点,主节点也会保存每个从节点的offset,这样主从节点就能知道互相之间的数据一致性情况。从节点发送psync runid offset命令给主节点从而开始主从同步,主节点会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,也可能是CONTINUE触发增量复制。
(10) 主从节点因为网络原因导致断开,当网络接通后,不需要手工干预,可以自动重新连接。
(11) 主节点如果发现有多个从节点连接,在快照同步过程中仅仅会生成一个RDB文件,用一份数据服务所有从节点进行快照同步。
(12) 从节点不会处理过期key,当主节点处理了一个过期key,会模拟一条del命令发送给从节点。
(13) 主从节点会保持心跳来检测对方是否在线,主节点默认每隔10秒发送一次heartbeat,从节点默认每隔1秒发送一个heartbeat。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值