Redis主从复制

关于复制

复制技术在存储服务中是一项常用的技术,数据库复制指的是发⽣在不同数据库实例之间,单向的信息传播的⾏为;通常由被复制⽅和复制⽅组成,复制⽅和被复制⽅之间建⽴网络连接,复制⽅式通常为被复制⽅主动将数据发送到复制⽅,复制⽅接收到数据存储在当前实例例,最终⽬的是为了保证双⽅的数据一致、同步。

关于Redis的复制,官网解释如下:
“At the base of Redis replication there is a very simple to use and configure master-slave replication that allows slave Redis servers to be exact copies of master servers”

复制流程

关于Redis的复制流程主要分为初始化复制和增量复制两部分

  • 初始化复制的流程如下:
  • SLAVE Redis节点启动
  • SLAVE节点发送同步命令(SLAVEOF MASTER_IP MASTER_PORT)
  • 主节点接收同步请求,fork子进程生成RDB文件,缓存所有的写入命令到额外的buffer中(circular buffer)
  • 主节点完成持久化,发生持久化文件到从节点
  • 从节点加载RDB文件
  • 从节点请求加载主节点之前缓存在buffer中的增量数据
  • 增量复制流程如下:
  • 主服务器写入命令记⼊额外的buffer,对写入的数据进行编号
  • 从节点发送目前同步到的点位,主节点发送增量数据

有以下几点需要注意:

  • 如果集群开启cluster模式,那么不允许手动在从节点上执行slaveof命令同步数据
  • 如果要断开主从复制,需要在从节点上执行 SLAVEOF NO ONE
  • 完成同步之前保证主从之间的socket链接不断开
  • 初始化复制过程中的buffer是每个slave独享的,复制结束后的增量复制是global buffer and global offset(replication backlog)
  • 以下几种情况可能会出现超时:
  • Non blocking connection timeout,从节点和主节点建立连接失败
  • Bulk transfer I/O timeout,从节点接受直接读的增量数据超时
  • Timed out master when we are an already connected slave,加载数据超时,和主节点的心跳丢失
  • 同步策略

    • disk (适用于通用场景)

    The Redis master creates a new process that writes the RDB file on disk. Later the file is transferred by the parent process to the slaves incrementally

    • socket(适用于慢磁盘,大带宽场景)

    The Redis master creates a new process that directly writes the RDB file to slave sockets, without touching the disk at all

关于复制的参数

  • repl-backlog-ttl
    • 说明:master没有slave一段时间会释放复制缓冲区的内存,repl-backlog-ttl用来设置该时间长度
    • 默认值:3600
    • 是否可以动态修改:yes
    • 值的范围:大于0
  • repl-timeout

    • 说明:复制链接超时时间,master和slave都有超时时间的设置。master检测到slave上次发送发送replconf命令的时间超过repl-timeout,即认为slave离线,清除该slave信息。slave检测到上次和master交互的时间超过repl-timeout,则认为master离线。需要注意的是repl-timeout需要设置一个比repl-ping-slave-period更大的值,不然会经常检测到超时。
    • 默认值:60
    • 是否可以动态修改:yes
    • 值的范围:大于0
  • client-output-buffer-limit

    • 说明:client output buffer限制,可以用来强制关闭传输缓慢的客户端。格式为client-output-buffer-limit,可以为normal、slave、pubsub。hard limit表示output buffer超过该值就直接关闭客户端。soft limit和soft seconds表示output buffer超过soft limit后只需soft seconds后关闭客户端连接
    • 默认值:
      client-output-buffer-limit normal 0 0 0
      client-output-buffer-limit slave 256mb 64mb 60
      client-output-buffer-limit pubsub 32mb 8mb 60
    • 是否可以动态修改:yes
    • 值的范围:[normal|slave|pubsub]
  • min-slaves-to-write

    • 说明:redis提供了可以让master停止写入的方式,如果配置了min-slaves-to-write,健康的slave的个数小于N,mater就禁止写入。master最少得有多少个good的slave存活才能执行写命令。这个配置虽然不能保证N个slave都一定能接收到master的写操作,但是能避免没有足够good slave的时候,master不能写入来避免数据丢失
    • 默认值:0
    • 是否可以动态修改:yes
    • 值的范围:大于等于0
  • min-slaves-max-lag

    • 说明:延迟小于min-slaves-max-lag的slave才认为是good slave
    • 默认值:10
    • 是否可以动态修改:yes
    • 值的范围:大于等于0
  • repl_backlog

    • 说明:复制缓冲区大小,这是一个环形复制缓冲区,用来保存最新复制的命令
    • 默认值:1mb
    • 是否可以动态修改:yes
    • 值的范围:内存单位

expire keys 如何同步

  • Slaves don’t expire keys, instead they wait for masters to expire the keys
  • However because of master-driven expire, sometimes slaves may still have in memory keys that are already logically expired