旧版的redis复制主要包括同步和命令传播
1) 同步操作将从库的状态更新至与主库同
2) 命令传播主要用于主库状态更改,导致主从不一致的情况
同步:
从库的同步操作主要通过SYNC命令完成
1) 从库向主库发送SYNC命令
2) 收到SYNC命令的主库执行BGSAVE,在后台生成RDB文件,备份同时,使用一个缓冲区记录从此时开始的所有写命令
3) BGSAVE执行完毕,主库将RDB文件发从给从库,从库接收并载入,将自身的数据更新至主库执行save时的状态
4) 主库将缓冲区命令发送给从库,从库更新自身状态至主库现在状态
命令传播
刚刚同步完的主从库处于数据一致的状态、此时若有写操作,会造成数据不一致,为了让主从数据回到一致的状态,主库对从库进行命令传播的操作,也就是将引起主从状态不一致的命令发送给从库执行,从而达到主从数据的一致
旧版复制
Redis2.8之前从库的复制:
1) 初次复制:从库之前没有复制过任何服务器,或者从服务器当前要复制的服务器和上次复制的服务器不同
2) 断线后复制:处于命令传播阶段的主从连接中断,从库主动连接主库,并继续复制主库
对于初次复制、Redis可以很好的完成工作,但对于断线重连,Redis采用的是全量复制,读取全部RDB文件
Note:
对于断线重连的情况,可以注意2个点:
1) 大部分主从库的数据是同步的、只有断线后主库新增数据不同步
2) 从库需要的只是那很小部分的不同步数据
新版复制
Redis2.8之后,使用PSYNC代替SYNC,包含完整重同步和部分重同步
1) 完整重同步用于处理初次复制的情况,和之前的版本保持一致
2) 部分重同步用于处理断线重连,只同步增量的不同步数据
增量同步通过复制偏移量和复制积压缓冲区及服务器ID来实现
1. 偏移量
1) 主从各自维护自己的偏移量,主向从传播N个数据时,累加自身偏移量
2) 从收到N个同步命令时,累加自身偏移量
2. 复制积压缓冲区:
1) 主库维护、长度固定、先进先出的队列,默认大小1M
2) 主向从进行命令同步时,还会写入复制积压缓冲区(保留偏移量)
3) 从库重新连接主库时,会把自身的偏移量发送给主,若这个偏移量依然位于复制积压缓冲区,执行部分重同步,否则执行全部重同步
3. 服务器ID
每个服务器运行时,自动生成,主从都有自己的ID,从库也就是靠这个运行ID,来判断当前连接的主库是不是之前复制的主库,是可以执行部分重同步,否则只能执行全量重同步
复制的实现:
1) 设置主库的地址和端口
2) 建立连接套接字
3) 发送ping命令
4) 身份验证
5) 发送端口信息
6) 执行同步
7) 命令传播
心跳检测
1) 检测主从server的网络连接状态
2) 辅助实现min-slaves选项
3) 检测命令丢失(offset)