首先从机需要发送自身携带的replid和offset向主机请求连接
replid:replid是所有主机在启动时会生成的一个固定标识,它表示当前复制流的id,当从机第一次请求连接时,主机会将自己的replid发送给从机,从机在接下来的请求都将携带这个replid,确认主从机在同一复制流中,如果中途主机宕机(重新启动会生成新的replid)或从机宕机但未开启持久化存储(replid保存在内存中,不开启持久化存储配置,重启会消失)都会导致replid丢失,从而执行全量复制
offset:offset表示当前的主机向复制缓冲区复制了多少数据,每当主机向复制缓冲区复制数据时,offset都会增加,从机也是通过记录上次的offset,来判断需要从哪里开始执行复制缓冲区的指令。如果从机因为某些原因断连,如果从机记录的offset没有被最新修改数据的指令在复制缓冲区覆盖,并且保存了replid,则可以进行增量复制,无需全量复制。
复制缓冲区:主机在想从机复制数据时并不会直接将数据复制给从机,而是将操作数据的指令存入数据缓冲区,并且记录offset,在将复制缓冲区传递给从机,从机根据自身记录的offset执行复制缓冲区内记录的指令以达到数据复制效果,复制缓冲区中的命令已满时,新命令会覆盖最早的旧命令,这也就导致了,如果从机请求复制数据时,它携带的offset已经被覆盖,那么他则必须全量复制,不过只要连接不断开,这种情况不会发生。
全量复制就是将从机数据清空,将主机数据完整的通过rdb文件复制到从机,增量复制是基于从机已有的数据和offset通过主机的复制缓冲区保存的指令进行复制,具体取决于从机是否拥有主机的replid以及保存的offset是否被新指令覆盖。
紧接着从机验证replid是否和自己相同,如果相同则证明时本次复制流中的从机,如果不是则证明不是,需要进行全量连接,全量连接时,主机会调用save执行进行数据快照生成rdb文件,rdb文件记录了主机中所有的数据,然后主机将rdb文件发送给从机实现全量复制,而如果replid相同则继续判断offset,如果offset存在于当前复制缓冲区的返回,则发送复制缓冲区的内容让从机数据进行增量复制,如果offset已经被覆盖,则仍然需要全量复制,主机还需发送版本信息进行验证主机从机的redis是否为同一版本,如果不为同一版本仍无法连接。
建立连接后,主机将按照既定周期源源不断的将复制缓存区内容发送给各个从机进行复制。