Updated at 2019-05-15 16:01

简介

Redis是个单线程的引用,为了充分利用多核/多线程机器的特点,往往需要部署多个Redis实例

复制

  1. 复制功能是Redis多实例之间数据一致的基础

  2. 被复制的服务器是主服务器,复制方被称为从服务器,一旦开启复制,主从之间的数据是一致的

  3. 旧版复制功能采用 先同步,再命令传播 方式实现

  4. 对于主从断线后重新复制这个场景而言,旧版复制的效率很低,因为重连后会重新同步主服务器的所有数据

  5. 新版Redis采用PSYNC代替SYNC,因为旧版的同步SYNC)开销非常大

    • 对于主服务器而言,同步需要先BGSAVE,再网络传输RDB文件

    • 对于从服务器而言,接收RDB文件期间整个服务器是阻塞的

  6. PSYNC有完整重同步和部分重同步两种模式,前者适用于从服务器初次同步,后者适用于主从断开重连时的重同步

  7. 部分重同步通过+CONTINUE命令,重同步时只传输断线期间的命令,所以效率比完整重同步高

  8. 部分重同步如何实现

    • 主从各自维护一个复制偏移量,主服务器每传输N个字节,偏移量就+N,从服务器每收到N个字节,偏移量就+N,断线重连后如果主从的复制偏移量不一致,则说明不主从不一致了
    • 主服务器会维护一个固定长度的FIFO队列,被称为复制积压缓冲区,命令传播时,每个命令还会写入这个缓存区
    • 当主从重连后,从会向主发送自己的偏移量,如果主从偏移量之差超过缓冲区的长度了,则完整重同步,否则主需要根据偏移量之差重新传播缓存区里的命令即可
  9. 命令传播期间的心跳机制

    • 从每秒钟都会向主发送REPLCONF ASK <复制偏移量>
    • 主服务可以通过INFO replication查看最近一次的ACK,lag属性代表这次ACK距现在的秒数,正常情况下是0秒或1秒,如果超过1秒则代表主从连接不稳定
    • 主服务器可以通过配置min-slaves-to-writemin-salaves-max-lag设置当从服务器少于n个时,或所有从服务器的lag都大于m时,主服务器会拒绝所有写命令
    • 如果在心跳期间,主服务器发现偏移量不一致时,主会根据偏移量只差,向从补发复制积压缓存区里的数据

哨兵模式

  1. 哨兵模式是一种能确保多实例之间高可用的一种方案。下图是一个典型的,稳定运行中的哨兵模式示意图

  2. Sentinel系统本质是使用--sentinel模式启动的Redis实例

  3. Sentinel启动流程

    • 初始化
    • 将Redis代码替换成Sentinel专用代码
    • 初始化Sentinel
    • 初始化Sentinel监视主服务器列表
    • 创建与主服务器的连接
  4. Sentinel是master的客户端,Sentinel会与master建立一个命令连接和订阅连接,前者用于发命令,接收命令回复,后者专门订阅master的__sentinel__:hello频道

  5. Sentinel默认每10秒,向master发送INFO命令,尝试获取返回的master信息,信息包括master的信息和下属的slave信息。

  6. 主观下线:当一个Sentinel没有收到master的PONG回复时,这个Sentinel会将master标记为主观下线

  7. 客观下线:Sentinel会向其它Sentinel询问主观下线master的状态,如果其它Sentinel也一致认为master下线了,则将master标记为客观下线,从而进行故障转移

  8. 一旦master客观下线,所有Sentinel会选举出一个领头Sentinel,领头对master进行故障转移

  9. 故障转移过程

    • 从下线master下属的slaver挑选一个,向他发送SLAVEOF on one,使它作为新的master
    • 让其它slaver复制新的master
    • 将已下线的master设置为新master的slaver

Redis      Redis