前言
主从复制是Redis集群保证数据一致性的重要机制,如果其中的某个从服务器由于网络中断等原因与主服务器断开连接后,从服务器重新连接上来时。为了保障主从数据的一致性,此时主服务器会发起一次同步命令。由于从服务器只是短暂的断开了一会儿,丢失的数据并不多。如果直接发起全量复制的话,就会很浪费资源,如果数据量很大的话,全量同步也会拖慢Redis集群的响应效率。此时Redis就需要增量复制来保障数据一致性了。
增量复制原理
在讲解增量复制之前,需要先了解以下几个名词概念:复制偏移量、复制积压缓存区、runID(服务器运行ID)
1、复制偏移量(offset)
在数据复制过程中,主服务器和从服务器均会维护一个复制偏移量,代表复制的进度。当主服务器向从服务器传播N个字节的数据时,主服务器的offset会增加N。从服务器接收到N个字节的数据时,从服务器的offset增加N。
2、复制积压缓存区
复制积压缓存区是主服务器维护的一个固定长度的队列,当主服务器接收到写命令时,不仅会发向所以从服务器,还会在将写命令保存至复制积压缓存区中,并且还会保存相对应的复制偏移量。所以复制积压缓存区保存的是最近一段时间内的所有写命令和offset。
3、服务器运行ID
在服务器启动时,主服务器和从服务器都会生成自己的运行ID,叫做runID。runID主要是用来当发生增量复制时,是否更换过主服务器。
增量复制过程:
如果从服务器是一个全新的服务器,或者发生过主从切换后的原主节点,这个时候需要发起全量同步。否则会发起增量同步,主服务器是否执行增量同步由以下判断返回
- 如果从服务器发送过来的runID和主服务器的runID不一致,则直接发起全量同步
- 计算从服务器和主服务器的复制偏移量不一致,则判断偏差开始的那个复制偏移量对应的数据是否还在复制积压缓存区中,如果不在了,则直接发起全量同步
当判断完成执行增量复制后,主服务器只需要根据从服务器发的offset,将复制积压缓存区中对应的写命令发送给从服务器即可。这样可快速的恢复从服务器的数据。