Redis设计与实现---复制

旧版复制实现

  • 同步:将从服务器的数据库状态更新至主服务器当前所处的数据库状态

                                       

  • 命令传播:在主服务器的数据库状态被修改,导致主从服务器的数据库状态不一致时,让主从服务器的数据库重新回到一致状态。当主服务器执行完命令之后,进行命令传播操作,将命令发送给从服务器执行,从服务器执行了相同命令。主从服务器再次回到一致状态。

缺陷

断线后重复制,需同步所有数据。实际可能只是一小部分数据缺失。

新版复制实现

  • 完整重同步:通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面写命令来进行同步

  • 部分重同步:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器将主从服务器连接断开期间执行的写命令发送给从服务器。

                                 

部分重同步的实现

  • 主服务器的复制偏移量和从服务器的复制偏移量
  • 主服务器的复制积压缓冲区
  • 服务器的运行ID

复制偏移量

执行复制双方------主服务器和从服务器分别维护一个复制偏移量:

主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量的值增加N。

从服务器每次收到主服务器传播来的N个字节数据时,将自己的复制偏移量的值加上N。

复制积压缓冲区

复制积压缓冲区是由主服务器维护的一个固定长度先进先出队列(当入队元素大于队列长度时,最先入队元素会被弹出。默认大小1MB。可以根据second(断线后重连平均时间)*write_size_per_second(平均每秒产生写命令数据量)来估算设置repl-backlog-size选项改变缓冲区大小。

重连同步流程:

  1. 当从服务器A(上图为例)断线重连后,向主服务器发送PSYNC命令,报告自己的偏移量为10086
  2. 主服务器收到命令后,检查偏移量10086之后的数据是否存在于复制积压缓冲区里。存在,向服务器发送+CONTINUE回复,表示数据同步将以部分重同步模式进行。(不存在,主服务器将对从服务器执行完整重同步操作)
  3. 主服务器将复制积压缓冲区10086之后的所有数据发送给从服务器
  4. 从服务器接收缺失数据,回到与主服务器一致的状态

服务器运行ID

每个Redis服务器,不论主服务器还是从服务器,都会有自己的运行ID。从服务器在对主服务器进行初次复制时,保存该主服务器的运行ID。当断线重连后,从服务器保存运行ID与连接的主服务器运行ID相同,可执行部分重同步。不同将执行完整重同步。

PSYNC命令流程图

心跳检测

在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:REPLCONF ACK <replication_offset>

其中replication_offset是从服务器当前的复制偏移量

  • 检测主从服务器的网络连接状态
  • 辅助实现min-slaves选项。min-slaves-to-write和min-slaves-max-lag防止主服务器在不安全的情况下执行写命令。
    min-slaves-to-write 3
    min-slaves-max-lag 10

    在从服务器数量少于3个,或者三个从服务器的延迟值(最后一次心跳检测距离现在过了多少秒)都大于或等于10秒时,主服务器将拒绝执行写命令

  • 检测命令丢失。偏移量不一致,会进行补发缺失数据的操作(Redis 2.8之前会命令丢失)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章