如何进行第一次同步?

  • 第一阶段,建立连接,全量复制。从库发送 psync ? -1? 是不知道主库的 runID(标识 redis 实例,启动时随机生成),offset=-1。主库发送 FULLRESYNC runID offset 告知 runID 和 offset
  • 第二阶段,主库执行 bgsave 获得 RDB 文件,然后同步给从库。从库清空数据库,然后加载数据。期间,主库将新的写操作放到 replication buffer
  • 第三阶段,将 replication buffer 发送给从库。

replication buffer 由 client-output-buffer-limit slave 参数设置,当这个值太小会导致主从复制链接断开,从而引发主从复制断开+主库重新 bgsave + send rdb,进而重复过程。

如何进行后续的增量复制?

master 会发送一连串的命令流来保持对 slave 的更新,以便于将自身数据集的改变复制给 slave:包括客户端的写入、key 的过期或被逐出等等。

如何从库多,主从服务存在什么问题?解决办法

主库就需要阻塞进行 fork 生成 RDB,传输 RDB 要占用带宽。
解决办法是,可以选择 “主-从-从” 的模式进行同步。

主从网络断开后又恢复,如何同步?

主库将增量复制同步给从库,其中增量内容是存放在 repl_backlog_buffer 环形缓冲区中,其中对应 master_repl_offset 和 slave_repl_offsetrepl_backlog_buffer 大小需要配置好,否则主库增量写完一轮覆盖了之前的记录,而从库还没有同步。如果请求的 offset 不存在,那么执行全量的 sync 操作,相当于重新建立主从复制。

replication buffer vs repl_backlog_buffer

replication buffer 用于初次同步时,生成+发送 RDB 文件时收到的写命令;部分同步时,过程中暂存写操作命令。每个 slave 对应一个。

repl_backlog_buffer 用于存储最近一段时间内的写操作命令的一个固定大小的循环缓冲区,用于实现部分同步。slave 共享一个。

为什么使用 RDB 而不是 AOF?

RDB 二进制传输效率高 + 恢复效率高。

参考链接