主从复制过程

数据同步演变过程
sync 同步Redis 2.8 版本之前,首次通信成功后,slave 会向 master 发送 sync 数据同步请求。然后master 就会将其所有数据全部发送给 slave,由 slave 保存到其本地的持久化文件中。这个过程称为全量复制。但这里存在一个问题:在全量复制过程中可能会出现由于网络抖动而导致复制过程中断。当网络恢复后,slave 与 master 重新连接成功,此时 slave 会重新发送 sync 请求,然后会从头开始全量复制。由于全量复制过程非常耗时,所以期间出现网络抖动的概率很高。而中断后的从头开始不仅需要消耗大量的系统资源、网络带宽,而且可能会出现长时间无法完成全量复制的情况。
psync 同步
Redis 2.8 版本之后,全量复制采用了 psync(Partial Sync,不完全同步)同步策略。当
全量复制过程出现由于网络抖动而导致复制过程中断时,当重新连接成功后,复制过程可以
“断点续传”。即从断开位置开始继续复制,而不用从头再来。这就大大提升了性能。
系统为每个要传送数据进行了编号,该编号从 0 开始,每个字节一个编号。该编号称为
复制偏移量。参与复制的主从节点都会维护该复制偏移量。
当 master 启动后就会动态生成一个长度为 40 位的 16 进制字符串作为当前 master 的复
制 ID,该 ID 是在进行数据同步时 slave 识别 master 使用的。通过 info replication 的
master_replid 属性可查看到该 ID。
当 master 有连接的 slave 时,在 master 中就会创建并维护一个队列 backlog,默认大小
为 1MB,该队列称为复制积压缓冲区。master 接收到了写操作数据不仅会写入到 master 主
存,写入到 master 中为每个 slave 配置的发送缓存,而且还会写入到复制积压缓冲区。其作
用就是用于保存最近操作的数据,以备“断点续传”时做数据补偿,防止数据丢失。
在 psync 数据同步过程中,若 slave 重启,在 slave 内存中保存的 master 的动态 ID 与续传 offset 都会消失,“断点续传”将无法进行,从而只能进行全量复制,导致资源浪费。 在 psync 数据同步过程中,master 宕机后 slave 会发生“易主”,从而导致 slave 需要从新 master 进行全量复制,形成资源浪费。Redis 4.0 对 psync 进行了改进,提出了“同源增量同步”策略。针对“slave 重启时 master 动态 ID 丢失问题”,改进后的 psync 将 master 的动态 ID 直接写入到了 slave 的持久化文件中。slave 易主后需要和新 master 进行全量复制,本质原因是新 master 不认识 slave 提交的psync 请求中“原 master 的动态 ID”。如果 slave 发送 PSYNC <原 master_replid> <repl_offset>命令,新master能够识别出该slave要从原master复制数据,而自己的数据也都是从该master复制来的。那么新 master 就会明白,其与该 slave“师出同门”,应该接收其“断点续传”
同步请求。而新 master 中恰好保存的有“原 master 的动态 ID”。由于改进后的 psync 中每个 slave都在本地保存了当前 master 的动态 ID,所以当 slave 晋升为新的 master 后,其本地仍保存有之前 master 的动态 ID。而这一点也恰恰为解决“slave 易主”问题提供了条件。通过 master的 info replicaton 中的 master_replid2 可查看到。如果尚未发生过易主,则该值为 40 个 0。
Redis 7.0 版本对复制积压缓冲区进行了改进,让各个 slave 的发送缓冲区共享复制积压
缓冲区。这使得复制积压缓冲区的作用,除了可以保障数据的安全性外,还作为所有 slave
的发送缓冲区,充分利用了复制积压缓冲区。
文章介绍了Redis从全量复制到psync的改进,包括断点续传、动态ID存储、以及Redis4.0的增量同步策略,以及Redis7.0对复制积压缓冲区的优化,以提升数据同步性能和效率。
9785

被折叠的 条评论
为什么被折叠?



