Redis -- 主从复制

1,主从复制

执行SLAVEOF命令或设置slaveof选项,让一个服务器复制另一个服务器;
初次复制:从服务器没有复制过任何服务器,或从服务器当前要复制的主服务器和上次复制的主服务器不同
断线后重复制:处于命令传播阶段的主从服务器由于网络原因而中断复制,自动重连后,继续复制主服务器
1.1 同步
从服务器向主服务器发送SYNC命令
收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录才能够现在开始执行的所有命令
当主服务器BGSAVE执行完毕后,会将生成的RDB文件发送给从服务器,从服务器接收并载入RDB文件
主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些写命令,完成主从的同步
时间主服务器从服务器
T0主服务器启动从服务器启动
T1执行SET k1 v1
T2执行SET k2 v2
T3向主服务器发送SYNC命令
T4接收到从服务器的SYNC命令,执行BGSAVE命令,创建包含键k1、k2的RDB文件,并用缓冲区记录接下来新的写入命令
T5执行SET k3 v3,将这个命令记录到缓冲区
T6执行SET k4 v4,将这个命令记录到缓冲区
T7BGSAVE命令执行完毕,向从服务器发送RDB文件
T8接收并载入主服务器发来的RDB文件,获取k1、k2键
T9向从服务器发送缓冲区保存的SET k3 v3,SET k4 v4写命令
T10接收并执行主服务器发来的两个SET命令,得到k3,、k4键
T11同步完成,主从服务器数据一致同步完成,主从服务器数据一致
1.2 命令传播
主服务器发生修改后,会将修改所执行的写命令发送给从服务器执行,从服务器执行完成后,达到主从一致
时间主服务器从服务器
T0主从服务器完成同步主从服务器完成同步
T1执行并传播SET k1 v1执行主服务器传来的SET k1 v1
T2执行并传播SET k2 v2执行主服务器传来的SET k2 v2
T3000执行并传播SET k3000 v3000执行主服务器传来的SET k3000 v3000
T3001主从服务器连接断开主从服务器连接断开
T3002执行SET k3001 v3001断线中…
T3003执行SET k3002 v3002断线中…
T3003主从服务器重连主从服务器重连
T3004向主服务器发送 SYNC 命令
T3005接收到从服务器发来的SYNC命令,执行BGSAVE命令,创建含k1~k3002的所有k的RDB文件,并使用缓冲区记录接下来新执行的写命令
T3006执行SET k3003 v3003,将这个命令记录到缓冲区
T3007BGSAVE命令执行完毕,向从服务器发送RDB文件
T3008接收并载入主服务器发来的RDB文件,获取k1~k3002键
T3009向从服务器发送缓冲区保存的SET k3003 v3003写命令
T3010接收并执行主服务器发来的SET命令,得到k3003键
T3011同步完成,主从服务器数据一致同步完成,主从服务器数据一致
由此可以看出,断线后重复制会从k1~k3002键全部通过SYNC生成RDB文件同步给从服务器,其中k1 ~ k3000都是没有必要的,而且SYNC性能低下
1.3 PSYNC
就版本SYNC复制功能在处理断线重复制情况下,从头开始写RDB文件的低效问题,2.8版本后使用PSYNC命令替换了SYNC

完整重同步

完整重同步:用于处理初次复制。与SYNC执行一样,通过主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令进行同步

部分重同步

部分重同步:用于处理断线后重复制。从服务器发生断线后重新连接主服务器时,主服务器可以将主从服务器断开期间执行的写命令发送给从服务器,从服务器只接收并执行这部分命令,就可以完成主从同步,提升效率
时间主服务器从服务器
T0主从服务器完成同步主从服务器完成同步
T1执行并传播SET k1 v1执行主服务器传来的SET k1 v1
T2执行并传播SET k2 v2执行主服务器传来的SET k2 v2
T3000执行并传播SET k3000 v3000执行主服务器传来的SET k3000 v3000
T3001主从服务器连接断开主从服务器连接断开
T3002执行SET k3001 v3001断线中…
T3003执行SET k3002 v3002断线中…
T3003主从服务器重连主从服务器重连
T3004向主服务器发送 PSYNC 命令
T3005向从服务器返回+CONTINUE回复,表示执行部分重同步
T3006?执行并传播SET k3003 v3003???执行主服务器传来的SET k3003 v3003???
T3007接收+CONTINUE回复,准备执行部分重同步
T3008向从服务器发送SET k3001 v3001、SET k3002 v3002命令
T3010接收并执行主服务器发来的SET命令,得到k3001、k3002键
T3011同步完成,主从服务器数据一致同步完成,主从服务器数据一致
1.4 部分重同步实现

复制偏移量

执行主从复制的主从都分别维护了一个复制偏移量
	主服务器向从服务器传播N个字节数据时,就将自己的复制偏移量+N
	从服务器收到主服务器传播的N个字节数据时,就将自己的复制偏移量+N
	
通过对比主从服务器的偏移量更容易确定服务器是否处于一致状态(相同即一致)

在这里插入图片描述

复制积压缓冲区

由主服务器维护的一个固定长度(fixed-size)的先进先出(FIFO)的队列,默认1M大小
主服务器的复制积压缓冲区会保存一部分最近传播的写命令,并会为队列中的每个字节记录相应的复制偏移量
当从服务器重连上时,会同PSYNC将自己的偏移量offset发给主服务器,而后主服务器会根据从服务器的复制偏移量来决定如何执行同步操作

部分重同步与完整重同步的选择
	如果从服务器offset之后的数据再复制积压缓冲区,则对从服务器执行部分重同步操作
	如果不在则对从服务器执行完整重同步操作
合理的设置复制积压缓冲区的大小,可以保证绝大部分断线情况下都能使用部分重同步操作,提供同步效率

在这里插入图片描述

服务器运行ID

每台服务器启动时都会自动生成40个随机的十六进制的字符作为服务器运行ID
初次复制时,主服务器会将自己的运行ID传输给从服务器保存
从服务器断线重连到主服务器时,从服务器会向链接的主服务器发送之前保存的主服务器的ID
	如果ID匹配,说明是同一个主服务器,可以尝试执行部分重同步操作
	不匹配,说明不是同一个主服务器了,需要执行完整重同步
1.5 PSYNC实现

PSYNC执行完整重同步和部分重同步情况

1.6 复制实现
设置主服务器的地址+端口:SLAVEOF 127.0.0.1 6379
建立套接字链接:从服务器根据ip+port创建链接主服务器的套接字
发送PING命令:通过发送ping检查套接字读写状态是否正常、是否可以正常处理命令请求
验证身份:从服务器设置了masterauth选型才需要进行身份验证
发送端口信息:从服务器执行REPLCONF listening-port <port-number> 向主服务器发送从服务器的监听端口
同步:从服务器向主服务器发送PSYNC命令,执行同步操作
命令传播:完成同步之后,主从服务器就会进入命令传播阶段
1.7 心跳检测
命令传播阶段,从服务器默认每秒一次向主服务器发送:REPLCONF ACK <复制偏移量> 

ACK作用
	检测主从服务器的网络连接状态
	辅助实现min-slaves选项:min-slaves-to-write和min-slaves-max-lag选项防止主服务器在不安全情况下执行写命令
	检测命令丢失:如果由于网络问题,主服务器传播给从服务器的写命令半途丢失,从服务器向主服务器发送REPLCONF ACK时,主服务器发现从服务器的复制偏移量比自己小,然后主服务器会根据从服务器提交的复制偏移量在复制积压缓冲区定位从服务器缺少的数据,重新发给从服务器

参考链接:
学习《Redis设计与实现》 笔记

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页