第15章 复制
Redis中, 用户可以通过SLAVEOF命令或者设置slaveof选项让一个服务器去复制(replicate)另一个服务器, 被复制的服务器为主服务器(master), 进行复制的服务器为从服务器(slave)
进行复制中的主从服务器双方数据库保存相同的数据, 称为”数据库状态一致”, 或简称”一致”
15.1 旧版复制功能的实现
Redis的复制功能分为同步(sync)和命令传播(command propagate):
同步
同步操作让从服务器的数据库状态更新至主服务器当前状态. 当客户端向从服务器发送SLAVEOF命令后, 就会先执行同步操作
从服务器向主服务器发送SYNC命令。
收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。
主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。
命令传播
同步操作完成后, 仍需要命令传播来保持主从服务器的一致. 命令传播操作用于在服务器的数据库状态被修改, 导致主从服务器的数据库状态出现不一致时, 让主从服务器的数据库重新回到一致状态.
主服务器会将自己执行的写命令, 也就是造成主从服务器状态不一致的命令, 发送给从服务器并执行.
15.2 旧版复制功能的缺陷
在Redis中,从服务器对主服务器的复制可以分为以下两种情况:
- 初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同。
- 断线后重复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重连接重新连上了主服务器,并继续复制主服务器。
旧版复制功能在断线后重复制时效率非常低. (使用的SYNC命令会重传大量冗余数据)
15.3 新版复制功能的实现
从Redis2.8开始, 使用PSYNC代替SYNC命令实现同步, PSYNC具有两种模式:
- 完整重同步(full resynchronization)用于处理初次复制情况
- 部分重同步(partial resynchronization)用于处理断线重复制情况, 主服务器可以将断开期间执行的写命令发送给从服务器, 从服务器只要执行这一部分命令重新实现一致.
15.4 部分重同步的实现
部分重同步功能由以下三个部分构成:
- 主服务器的复制偏移量(replication offset)和从服务器的复制偏移量: 主服务器每次发送N字节数据, 就让复制偏移量加N; 从服务器每次收到N个字节的数据时, 就将自己的复制偏移量加N.
- 主服务器的复制积压缓冲区(replication backlog): 一个固定长度的FIFO队列, 保存着一部分最近传播的写命令(以及相应的偏移量)
- 服务器的运行ID(run ID): 40个随机的十六进制字符, 用于标识服务器. 从服务器重连到主服务器后, 比较之前保存的运行ID和当前主服务器运行ID, 若相同, 则部分重同步; 否则说明是不同的主服务器, 执行完整重同步操作.
15.5 PSYNC命令的实现
15.6 复制的实现
设置主服务器的地址和端口
建立套接字连接
发送ping命令
身份验证
发送端口信息
同步
命令传播
15.7 心跳检测
命令传播阶段, 从服务器默认以每秒一次的频率发送 REPLCONF ACK <replication_offset>
主要作用:
- 检测主从服务器的网络连接状态
- 辅助实现min-slaves配置选项, 可以配置min-slaves-to-write和min-slaves-max-lag选项来防止主服务器在不安全情况(从服务器数量小于xx, 或从服务器延迟高于xxx)下执行写命令.
- 检测命令丢失
- Title: 第15章 复制
- Author: Huan Lee
- Created at : 2023-08-28 21:21:57
- Updated at : 2024-02-26 04:53:15
- Link: https://www.mirthfullee.com/2023/08/28/notion-第15章 复制-dca76475/
- License: This work is licensed under CC BY-NC-SA 4.0.