这里主要说redis主从复制的4种情况
1. slave初次连接到master。连接建立完成之后,从向主发送psync ? -1 命令,主动要求进行全同步, 主执行bgsave,并将执行bgsave期间产生的变化写入到复制缓冲当中,执行完bgsave之后,将文件发送给从,并把复制缓冲区当中的命令发送给从。当数据同步完成以后,在此后的时间里主从维护着心跳检查来确认对方是否在线,每隔一段时间(默认10秒,通过repl-ping-slave-period参数指定)主节点向从节点发送PING命令判断从节点是否在线,而从节点每秒1次向主节点发送REPLCONF ACK命令,命令格式为:REPLCONF ACK {offset},其中offset指从节点保存的复制偏移量,作用一是汇报自己复制偏移量,主节点会对比复制偏移量向从节点发送未同步的命令,作用二在于判断主节点是否在线,从库接送命令并执行,最终实现与主库数据相同。
先说一下 几个复制中的概念
复制挤压缓冲区。主维护一块内存,用于保存最近产生变化的命令,是一个环形的FIFO队列,如果从的repl ack的偏移量不在主的缓冲区当中,则需要进行一次全同步
复制偏移量:主库和从库分别各自维护一个复制偏移量(可以使用info replication查看),用于标识自己复制的情况,在主库中代表主节点向从节点传递的字节数,在从库中代表从库同步的字节数。每当主库向从节点发送N个字节数据时,主节点的offset增加N,从库每收到主节点传来的N个字节数据时,从库的offset增加N。因此offset总是不断增大,这也是判断主从数据是否同步的标志,若主从的offset相同则表示数据同步量,不通则表示数据不同步
runid。每个redis实例在启动时候,都会随机生成一个长度为40的唯一字符串来标识当前运行的redis节点,查看此id可通过命令info server查看。当主从复制在初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来,当断线重连时,从节点会将这个runid发送给主节点。
主节点根据runid判断能否进行部分复制:
如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会更具offset偏移量之后的数据判断是否执行部分复制,如果offset偏移量之后的数据仍然都在复制积压缓冲区里,则执行部分复制,否则执行全量复制;
如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的redis节点并不是当前的主节点,只能进行全量复制;
2.psync。当主从断开连接 重新连上的时候 ,从会向主发送psync命令,
参考链接 https://juejin.im/post/5b67029c6fb9a04fa42fd592
https://lanjingling.github.io/2015/11/17/redis-mast-slaveof/