今天来详细介绍一下Redis的全量复制和增量复制。
1.全量复制
全量复制是Redis早期唯一支持的复制方式,也是主从之间第一次建立复制时必须的过程。
触发全量复制的命令是psync和sync。
下面介绍一下全量复制的流程。
1.1 主节点bgsave
当主节点接收到从节点的同步数据请求,并且决定进行全量复制的时候,主节点执行bgsave命令保存RDB文件到本地。
1.2 主节点发送RDB文件到从节点
主节点发送RDB文件给从节点,从节点将接受的RDB文件保存到本地并直接作为从节点的数据文件。
对于数据量较大的主节点,传输文件这一步是十分耗时的,如果传输文件总时间超过 repl-timeout 所配置的值(默认60秒),从节点会放弃接收RDB文件并清理已下载的RDB文件,导致全量复制失败。
网卡带宽理论峰值大约100MB/秒,在不考虑其他进程占用带宽的情况下,60秒可以传输6GB的RDB文件,所以一般超过6GB的主从复制需要格外当心,极易出现主从复制超时的情况。
1.3 同步主节点客户端缓冲区数据
从主节点开始创建RDB文件到从节点接受RDB文件完毕期间,主节点依然响应读写命令,主节点会把这段时间内的写命令数据保存在复制客户端缓冲区内,当客户端加载完RDB文件后,主节点再把缓冲区内的数据发送给从节点,保证数据的一致性。
缓冲区大小默认配置 client-output-buffer-limit slave 256mb 64mb 60,如果60秒内缓冲区消耗持续大于64MB或者直接超过256MB时,主节点将直接关闭复制客户端连接,造成全量复制失败。所以运维需要根据主节点的数据量和写命令的并发来调整 client-output-buffer-limit slave 配置,避免再全量复制期间客户端缓冲区溢出导致全量复制失败。
1.4 从节点清空数据
从节点接收完RDB文件后会先清空自身旧数据。
1.5 从节点加载RDB文件
从节点清空完自身旧数据之后,开始加载RDB文件,如果RDB文件过大,这一步操作依然比较耗时。
对于做读写分离的场景,从节点也负责响应命令。如果从节点此时正处于全量复制阶段,那么从介蒂安在响应读命令时可能拿到过期或者错误的数据。对于这种场景,Redis提供了 slave-serve-stale-data 参数,默认开启。如果开启则从节点依然响应所有命令。对于数据一致性要求高的场景可以关闭这个设置,关闭之后从节点除了info和slaveof命令之外所有的命令都只返回"SYNC with master in progress"。
1.6 执行AOF
如果从节点开启了AOF持久化功能,他会立即做bgrewriteof操作,用于保障全量复制后AOF持久化文件立即可用。
可以看到全量复制是一个十分耗时的操作,他的开销时间主要包括:
主节点bgsave时间
RDB文件网络传输时间
从节点清空旧数据树碱
从节点加载RDB文件时间
可能的AOF重写时间
当主节点数据达到6GB左右,在带宽资源良好并且全量复制没有失败的情况下,从节点发起的全量复制总耗时在2分钟左右,并且再次期间会大量消耗服务器的CPU、内存和网络资源,所以除了第一次复制时采用全量复制在所难免意外,对于其他场景应该尽量避免全量复制的发生。
2.增量复制
增量复制时Redis针对全量复制过高开销做出的一种优化措施,使用psync {runId} {offset}命令实现,下面介绍一下增量复制的流程。
2.1 主从网络中断
当主从网络发生中断时,如果中断时间超过 repl-timeout 时间(默认60秒),主节点会认为节点故障并且中断复制连接。
2.2 复制积压缓冲区
主从连接中断期间主节点依然响应命令,虽然写命令无法发送给从节点,但是复制积压缓冲区可以保存最近的写命令。
2.3 网络恢复
当主从节点之间网络恢复之后,从节点会再次连上主节点。
2.4 从节点请求同步
从节点会把自身的已复制偏移量和主节点的运行ID,作为参数发送sync命令到主节点请求数据同步。
2.5 主节点响应同步类型
主节点接收到sync命令后先核对参数runId与自身运行ID是否一致,如果不一致,则响应+FULLRESYNC {runId} {offset},触发全量复制。
之后根据offset在自身复制积压缓冲区中查找,如果找不到,说明复制积压缓冲区中的数据不足以做增量复制,则响应+FULLRESYNC {runId} {offset},触发全量复制。
如果参数runId与自身运行ID是否一致并且offset在自身复制积压缓冲区中存在,那么返回+CONTINUE,触发增量复制。
2.6 增量复制
主节点把根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态。
可以看到增量复制是一个市场简单的过程,可以很好的解决主从复制之间因为网络短时间中断造成的数据不一致问题。
扫码关注,不迷路





