1) 主服务器的复制偏移量和从服务器的复制偏移量;
主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量的值加N;
从服务器每次收到主服务器传播来的N个字节的数据时,就将自己的复制偏移量的值加上N。
2) 主服务器的复制积压缓冲区;
由主服务器维护的一个固定长度队列,默认为1M,当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令入队到复制积压缓冲区里面。
3) 服务器的运行ID。
每个服务器在启动时随机生成运行ID(runid)。
1)从服务器向主服务器发送PSYNC命令,携带主服务器的runid和复制偏移量;
2)主服务器验证runid和自身runid是否一致,如不一致,则进行全量复制;
3)主服务器验证复制偏移量是否在积压缓冲区内,如不在,则进行全量复制;
4)如都验证通过,则主服务器将保持在积压区内的偏移量后的所有数据发送给从服务器,主从服务器再次回到一致状态。
1) 只有当 从服务器 的携带的主服务器runid和offset都符合,Redis才会采用增量同步的策略,存在着很大的局限性;
2) 因此 从服务器 重启、更换主服务器、以及断连时间过长,redis都会采用全量同步的策略。
采用验证数据源服务器的RunID,也就是Master的RunID,所有的Slave保留的都是同一个RunID;
当进行master切换时,源服务器的RunID是不变的,因此可以进行增量同步。
即使源RunID是一致的,但是不同的从服务器获得的数据进度是不一致的,也就是复制偏移量不一致;
另外当从服务器被提升为源服务器后,源RunID也会随之改变,因此当源RunId改变时,Redis需要记录从上一个源RunID同步数据时的复制偏移量,以便对从服务器进行数据一致性验证;
例如集群里有A、B、C三个redis服务器,A为主服务器,B和C为从服务器。
当A的复制偏移量为1000,B的复制偏移量为1000,C的复制偏移量为900。
1、A下线,提升B为主服务器:
这时B需要设置从A同步数据时的复制偏移量,也就是1000,记录1000以前的数据源是A,1000以后的数据源是B;
当C切换主服务器到B时,携带源RunID(A)和偏移量(900),到B进行验证,则B将900以后的数据同步到C,同时C设置偏移量为900后的数据源为B。
2、A下线,提示C为主服务器:
当B切换主服务器到C时,只能进行全量同步
1)为了使服务器重启后可以进行增量同步,则每个Redis需要保持RDB文件,RDB文件除了保存当前内存数据外,亦需要保存当前源RunID和复制偏移量
2)保留两份RDB文件,一份为当前RDB,一份为上一个时间点的RDB。
积压缓冲区的大小决定了同步数据的时间有效期,可以适当加大,或采用文件磁盘的方案,减少内存的使用
1)满足服务重启、切换主服务后继续进行增量同步;
2)改动量相对较少,风险可控。
1)频繁的切换主服务,可能会导致全量同步;
2)服务下线后,只能以从服务再次加入;
3)从服务切换主服务时,如果切换的主服务数据落后于从服务,则会导致全量同步。
1)如MR先于MR’下线,则MR上线时,使用上一个时间点的RDB文件恢复,以免因MR数据领先与MR’,导致数据全量同步;
2)系统下线后应及时上线,避免因断连时间过长导致数据全量同步。