Redis——复制

1,在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制另一个服务器。被复制的服务器我们称呼为主服务器,而对主服务器进行复制的服务器则被称为从服务器。
2,旧版复制功能的实现
redis的复制功能分为同步和命令传播两个操作:
1)同步
同步操作用于将从服务器的数据库状态更新至主服务当前所处的数据库状态。当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作。从服务器对主服务器的同步操作需要通过向主服务器发送SYNC命令来完成。SYNC命令的执行步骤:
-从服务器向主服务器发送SYNC命令。
-收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有命令。
-当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。
-主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。
2)命令传播
命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。经过同步后主从服务器的状态将达到一致,但这种一致并不是一成不变的,每当主服务器执行客户端发送的写命令时,主服务器的数据库就有可能会被修改,并导致主从服务器状态不在一致。这个时候主服务器需要对从服务器执行命令传播操作。
这种复制功能的缺陷,从服务器对主服务器的复制可以分为以下两种:
-初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同。这种可以很好的完成复制
-断线后复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重连接重新连上了主服务器,并继续复制主服务器。这种情况下旧版复制功能就会造成效率低下。
3,新版复制功能的实现,为了解决旧版复制功能中的问题,新版引入了部分重同步模式,当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态。
4,部分重同步的实现细节主要有3部分构成:
1)复制偏移量
主服务器和从服务器会分别维护一个复制偏移量:主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量的值加上N。从服务器每次接收到主服务器传播来的N个字节数据时,就将自己的复制偏移量的值加上N。通过对比主从服务器的复制偏移量,程序可以很容易知道主从服务器是否处于一致状态。
2)复制积压缓冲区
复制积压缓冲区是由主服务器维护的一个固定长度先进先出队列,默认大小为1MB。这里面保存着一部分最近传播的写命令。并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量。当从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,如果offset偏移量之后的数仍然存在于复制积压缓冲区里面,那么主服务器将对从服务器执行部分同步操作。否则,执行完整重同步操作。需要注意的是,这个缓冲区的大小可以根据需要进行设置。
3)服务器的运行ID
5,复制的实现步骤
1)设置主服务器的地址和端口,将主服务器的地址和端口保存到服务器状态的masterhost属性和masterport属性
2)建立套接字连接
3)发送PING命令,通过发送PING命令可以检查套接字的读写状态是否正常
4)进行身份验证
5)发送端口信息
6)同步
7)命令传播
6,心跳检查
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令REPLCONF ACK 从服务器当前便宜量,这样做有3个作用:检测主从服务器的网络连接状态、辅助实现min-slaves选项、检测命令丢失。前面两个好理解,主要记录一下检测命令丢失:
如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失,那么当从服务器向主服务器发送REPLCONF ACK命令时,主服务器将发现从服务器当前的复制偏移量少于自己的复制偏移量,然后主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区里找到从服务器缺少的数据,并将这些数据重新发送给从服务器。

猜你喜欢

转载自blog.csdn.net/xiaoan08133192/article/details/115374239
今日推荐