8.2 主备复制(replication)
数据复制为故障转移提供了基础
写入节点和读取节点的分离,提升性能
复制多副本关键问题是保证数据一致性。不同存储系统架构下方案不同,有的采用客户端双写,有的采用存储层复制。Redis采用主备复制的方式保证一致性,即所有节点中,有一个节点为主节点(master)它对外提供写入服务,所有的数据变更由外界对master的写入触发,之后Redis内部异步地将数据从主节点复制到其他节点(slave)上。
8.2.1 主备复制流程
master对外提供读写服务
slave作为数据备份,拥有全量数据,只提供读服务。
主备复制由slave主动触发,主要流程如下:
1)slave向master发起SYNC命令。这一步在slave启动后触发,master被动将新slave节点加入自己的主备复制集群。
2)master收到SYNC后,开启BGSAVE操作。
3)BGSAVE完成后,master将快照发送给slave。
4)发送期间,master收到来自客户端的新的写命令,除了正常响应外,再存一份到backlog队列。
5)快照发送完成后,master继续发送backlog队列信息。
6)backlog发送完成后,后续的写操作同时发给slave,保持实时的异步复制。
slave处理逻辑如下:
发送完SYNC后,继续对外提供服务。
开始接收master快照信息,此时,将slave现有数据清空,将master快照写入自身内存
接收backlog内容并执行它,即回放,期间对外提供读请求。
继续接收后续来自master的命令副本继续回放,保持数据和master一致。
如果多个slave节点并发发送SYNC命令给master,建立主备关系,只要在第二个slave的SYNC命令发生在master完成BGSAVE之前,第二个slave将收到和第一个slave相同的快照和后续backlog;否则,第二个slave的SYNC将触发master的第二次BGSAVE。
8.2.2 断点续传
每次当slave通过SYNC和master同步数据时,master都会dump全量数据并发发送。
如果slave网络断开很短时间在重连上时,做全量dump会导致大量已经存在的数据的无效开销。最好就是只同步断开期间的少量数据。
Redis的PSYNC(Partial Sync)可以替代SYNC,做的master-slave基于断点续传的主备同步协议。master-slave两端通过维护一个offset记录当前已经同步过的命令,slave断开期间,master的客户端命令会保持在缓存中,在slave重连之后,告知master断开时的最新offset,master将缓存中大于offset的数据发送给salve,而断开前已经同步过的数据,则不再重新同步,这样减少了数据传输开销。