Redis主从库数据同步

  • redis主从库模式

      • 高可靠性包含两层含义:数据尽量少丢失,服务尽量少中断
      • 前者使用AOF和RDB可以保证
      • 后者使用主从库模式保证
      • 读操作:主库、从库都可以接收
      • 写操作:⾸先到主库执⾏,然后,主库将写操作同步给从库
      • redis在主从数据库之间的复制是异步的,这意味着,主数据库执行完客户端请求的命令后会立即将命令发送给请求的客户端,并同步到从数据库,而不会等待从数据库接收到命令后再返回给客户端,因此该情况就会存在一定的数据不一致性风险,也就是redis不保证强一致性,而是通过从库策略追赶与主数据库的数据差异,以保障主从状态一致

  • 全量复制(主从库第一次同步)

      • 5b3H3V.png
      • 从库通过replicaof命令,向主库发送psync命令(参数runID为主库id,offset为复制进度)
      • 主库收到psync命令后,返回FULLRESYNC响应命令(参数为主库runID和主库⽬前的复制进度 offset),主从库开始同步
      • 主库执⾏bgsave命令,⽣成RDB⽂件,接着将⽂件发给从库,从库接收文件后清空当前数据库,加载RDB文件
      • 主库同步RDB文件并不会阻塞,会将期间的写请求记录在专⻔的replication buffer
      • 主库完成RDB文件发送后,会把replication buffer中的修改操作发给从库,从库执行这些操作后就完成了数据同步
      • 5b3l79.png
      • 多个从库连接到同一主库,会导致主库压力增大(主要是fork子进程会阻塞主线程,传输RDB文件会占用主库网络带宽),此时可以使用主从级联模式
      • Redis在全量复制时,既支持先生成RDB文件,再把RDB文件传给从库,也支持在主库上直接通过socket把数据传给从库,这称为无盘复制

  • 基于长连接的命令传播

    ​ 一旦主从库完成全量复制,他们之间会维护一个网络连接,主库通过该连接把接受到的命令操作同步给从库,避免频繁建立连接的开销


  • 增量复制

      • 网络断连或阻塞会导致主从库无法进行命令传播,而重新进行一次全量复制开销过大,此时主从库使用增量复制同步数据
      • 主从库断开后,主库会把期间收到的写操作命令写入replication buff和repl_backlog_buffer缓冲区中
      • repl_backlog_buffer是一个环形缓冲区,slave_repl_offset为从库下标,master_repl_offset为主库下标
      • 主从库连接恢复后,从库首先发送psync命令,并把自己当前的slave_repl_offset发给主库
      • 主库把处于master_repl_offset和slave_repl_offset之间的命令操作同步给从库完成同步
      • 由于repl_back_log_buffer是一个环形缓冲区,当主从库读取速度差异过大有可能导致从库未读的操作被主库的新写操作覆盖,造成主从库数据不一致
      • 缓冲空间⼤⼩ = 主库写⼊命令速度 * 操作⼤⼩ - 主从库间 ⽹络传输命令速度 * 操作⼤⼩,实际应用中考虑其他突发情况,通常把这个缓冲空间扩大一倍
      • 可以考虑使用切片集群分担单个主库的请求压力
      • repl_backlog_buffer是所有从库共享的
      • 由于repl_backlog_buffer存在覆盖的情况,重连后主库会根据从库的slave_repl_offset选择全量复制还是增量复制