- redis通过slaveof命令,放一个服务器去复制另一个服务器,一个为主服务器,另一个为从服务器
- 主从服务器保存相同的数据称为一致
旧版本的复制实现
- redis的复制功能分为同步和命令传播两个操作
- 同步用于将从服务器更新至与主服务器数据相同的数据库状态
- 命令传播用于当主服务器上存在修改,导致主从不一致的情况下,将主从服务器的数据库状态重回一致
同步
- 当从服务器收到salveof命令时,会向主服务器发生sync命令
- 主服务器收到sync命令行,会执行bgsave命令,生成RDB文件。并将RDB文件发生给从服务器
- 从服务器接收到RDB文件后,将RDB载入内存,将数据库状态更新至主服务器执行BGSAVE时的状态
- 主服务器将RDB重写缓冲区中的数据发送给从服务器执行
- 从服务器执行完重写缓冲区的命令后达到和主服务器相同的数据库状态
命令传播
- 同步完成后,主服务器的所有修改操作都会发送到从服务器
- 从服务器执行完修改命令后,重新达到数据库状态的一致性
问题
- 当出现连接断线时
- 从服务器重新发送sync命令,主服务器重新生成RDB文件,传送给从服务器载入
- RDB文件包含了大量的从服务器已经存在的键值对,这种做法是十分低效的
- 主服务器生成RDB文件需要消耗CPU和磁盘IO资源
- 传送RDB文件耗费带宽
- 从服务器载入RDB文件,服务处于阻塞状态
新版本复制实现
- 新版采用了psync来代替sync命令
- psync分文完整重同步和部分重同步
- 完整重同步和sync完全相同
- 部分重同步则会在断线之后,只发送在断线期间的写命令即可实现主从服务器数据库状态的
部分重同步的实现
- 部分重同步由三个部分构成
- 主服务器复制偏移量和从服务器复制偏移量
- 主服务器复制挤压缓冲区
- runid
复制偏移量
- 主服务器每次向从服务器发送N个字节的数据时,复制偏移量加N
- 从服务器每次接收N个字节,复制偏移量会加N
- 两个偏移量不一致时,说明主从不一致
复制挤压缓冲区
- redis会维护一个FIFO的大小为1MB的复制挤压缓冲区
- 当从服务器发送psync命令时,检查从复制的偏移量是否在复制挤压缓冲区中
- 在的话, 发送+COUNTINUE命令,将偏移量之后的数据发送给从服务器
- 不在的话则进行完整重同步
runid
- 每个服务器初始化时,都会生成一个唯一的runid
- 当从服务器首次复制主服务器时,执行完完整重同步之后,会保存主服务器的runid
- 从服务器重新连接主服务器时,会发送runid,如果runid和主服务器不一致则会导致完整重同步
psync命令实现
- 当首次接收到slaveof命令时,发送psync ? -1 命令进行完整重同步
- 如果复制过主服务器,重新复制时,会发生psync runid offset命令
- 如果返回 +flulresync runid offset回复,标识需要进行完整重同步
- 返回+countinue,部分重同步操作,从服务器只需要等待主服务器发送复制积压缓冲区的数据即可
- 回复-ERR时,不识别psync,需要执行sync命令
复制的实现
步骤1:设置主服务器的地址和端口
- slaveof是一个异步命令,在完成masterhost和masterport设置完成之后,就会向客户端恢复ok
- 实际的工作才刚刚开始
步骤2:建立套接字
- 建立套接字成功之后,从服务器会为套接字关联一个专门处理复制工作的文件事件处理器
- 主服务器接收到从服务器的连接之后,会为从服务器创建相应的客户端状态
- 从服务器作为主服务器的客户端
步骤3:ping
- ping的两个作用
- 判断主从之间是否网络通畅
- 判断主服务器是否可以正常接收处理命令
步骤4:身份验证
步骤5:发送端口
- 从服务器会将自己监听的端口发送给主服务器
步骤6:同步
- 从服务器发送psync命令,根据主服务器的回复决定什么重同步方式
- +FULLRESYNC runid offset 进行完整重同步
- +CONTINUE 进行部分重同步
- -ERR 不支持psync,使用sync同步
步骤7:命令传播
- 当完成同步之后,主服务器处理写命令之后,会将命令传播给从服务器,从而恢复一致性
心跳检测
- 在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令
- REPLCONF ACK offset 从服务器当前读复制偏移量
- 心跳检测的作用
- 检测主从服务器之间网络的联通性
- 主从服务器之间会互发replconf ack,一定时间内没有收到回复则连接有问题
- 辅助实现min-slaves选项
- min-slaves选项
- min-slaves-to-write 3 从服务器小于三个时
- min-slaves=max-lag 10 延时大于等于10秒时
- 当满足该条件时,主服务器就会拒绝执行写命令
- min-slaves选项
- 检测命令丢失
- 当主服务器接收到replconf ack命令中从服务器的复制偏移量,发现少于主服务器的复制偏移量时,会检查复制挤压缓冲区是否包含该偏移量,有的话会将数据传输给从服务器
- 检测命令丢失是在没有断线的情况下进行检测,而部分重同步是在断线之后执行的
- 检测主从服务器之间网络的联通性