旧约
1. 新slave从属于master
1.1 同步
- 新slave向master发送SYNC命令
- master在接受到SYNC命令后,执行BGSAVE命令,在子进程中创建一份RDB数据。并且将开始创建RDB数据到结束创建的时间段内所执行的命令,记录在缓冲区中。
- 将RDB备份发给slave,slave执行。
- 将缓冲区中的命令,发送给slave,slave执行。
1.2 命令传播
master还是会继续接收各种写请求,要维持主从一致的话,就需要master将新的写命令继续传递给slave,让slave执行,
2. 旧slave掉线重连恢复
在旧约下,旧slave掉线重连恢复也会执行以上的操作。
但注意一点,master和slave执行SYNC操作,都是会耗费大量的算力、带宽并且会影响正常响应client。掉线重连并不需要全量的RDB,只需要掉线到恢复这个段时间内的写类型操作语句即可。
以上就是旧约在处理掉线重连问题上的缺陷。
新约
Redis 2.8以后,使用PSYNC命令进行主从之间的同步,考虑到了旧约的缺陷,分以上两种情况进行全量同步(full resynchronization)和部分同步(partial resynchronization)。
partial resynchronization实现原理
master中有一个复制积压缓冲区,以字符形式记录着一段时间内执行过的写命令,每个字符对应一个offset。
每次master向slave进行命令传播时,会将对应的offset也传递过去,slave会保存目前执行的最大offset。当发生掉线重连时,会将offset回传给master,如果复制积压缓冲区中还保留着相应的offset,那么master就执行partial resynchronization,把对应的指令传给slave,避免了RDB带来的性能影响。
复制积压缓冲区是一个固定size的FIFO队列,不可能记录着所有的写指令,所以当offset已经不存在于缓冲区中,就会执行full resynchronization。
实际应用
复制积压缓冲区的size,要根据每秒平均写命令量级 * 平均掉线重连的时间做匹配,避免full resynchronization。
网友评论