Redis设计与实现---Sentinel

Sentinel

Redis的高可用性解决方案:由一个或多个Sentinel实例组成的系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

                                        

对于每个被Sentinel监视的主服务器来说,Sentinel会创建两个连向主服务器的异步网络连接:

  • 命令连接:用于向主服务器发送命令,并接收命令回复
  • 订阅连接:用于订阅主服务器的_sentinel_:hello频道

获取主服务器信息

Sentinel默认会以每十秒一次的频率,通过命令连接向被监视的主服务器发送Info命令,获取到主服务器的当前信息。

  • 主服务器本身的信息,包括run_id以及服务器角色
  • 主服务器属下所有从服务器的信息,IP地址和端口号。根据这些Sentinel可以自动发现从服务器。

获取从服务器信息

当Sentinel发现主服务器有新的从服务器出现时,Sentinel除了会为这个新的从服务器创建相应的实例结构之外,还会创建连接到从服务器的命令连接和订阅连接。

创建命令连接之后,会以每十秒一次的频率通过命令连接向从服务器发送INFO命令。获取到以下信息,更新实例结构

  • 从服务器运行ID run_id
  • 从服务器角色role
  • 主服务器IP地址以及端口号
  • 主服务器连接状态master_link_status
  • 从服务器优先级slave_priority
  • 从服务器的复制偏移量slave_repl_offset

向主从服务器发送信息

默认情况下,Sentinel会以每两秒一次的频率,通过命令连接向所有被监视的主服务器和从服务器发送命令。

PUBLISH _sentinel_:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

接收来自主从服务器的频道消息

当sentinel与主从服务器建立起订阅连接之后,就会通过订阅连接,向服务器发送命令。Sentinel对_sentinel_:hello频道的订阅会一直持续到与服务器的断开为止。

                                            

通过这种机制,Sentinel为主服务器创建的实例结构中的sentinels字典保存了所有同样监视这个主服务器的其他Sentinel资料

创建连向其他Sentinel的命令连接

当Sentinel通过频道信息发现一个新的Sentinel时,不仅会为新Sentinel在sentinels字典中创建相应的实例接哦股,还会创建一个连向新Sentinel的命令连接,而新Sentinel也同样会创建连向这个Sentinel的命令连接。(只会创建命令连接,不创建订阅连接。订阅连接是为了通过频道信息发现未知的新Sentinel)

                                                    

检测主观下线

默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他Sentinel在内)发送PING命令。并通过实例返回的PING命令回复判断实例是否在线。

  • 有效回复:实例返回+PONG、-LOADING、-MASTERDOWN三种回复的其中一种
  • 无效回复:除上面三个回复之外的其他回复,或者指定时限内没有返回任何回复。

Sentinel配置文件中down-after-milliseconds指定了判断实例进入主观下线所需的时间长度。如果一个实例在down-after-milliseconds毫秒内,连续返回无效回复。Sentinel会修改这个实例所对应的实例结构,flags属性中打开SRI_S_DOWN表示,以此表示该实例进入主观下线状态。

                                                 

注意:

  • 设置down-after-milliseconds的标准,是针对所有实例的,包括主服务器、从服务器、Sentinel
  • 监视同一个主服务器的各个Sentinel来说,设置的down-after-milliseconds值不同,判断主观下线的标准也就不一样。

检查客观下线状态

当Sentinel将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其他Sentinel进行询问。当接收到足够数量的已下线(可以是主观下线或者客观下线,为啥还有客观下线?因为每个Sentinel的配置可能不同)判断之后,会将从服务器判定为客观下线,并对主服务器执行故障转移操作

发送命令

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>

回复命令

接收回复命令

根据其他Sentinel的命令回复,统计其他Sentinel同意主服务器已下线的数量,当达到配置(quorum参数配置)指定的判断客观下线所需的数量时,将主服务器实例结构flags属性的SRI_O_DOWN标识打开,表示主服务器已经进入客观下线状态。

选举领头Sentinel

  • 监视同一个主服务器的多个在线Sentinel中任意一个都有可能成为领头Sentinel
  • 每次进行选举之后,所有Sentinel配置纪元都会自增一次
  • 在一个配置纪元里,所有Sentinel都有一次设置局部领头Sentinel的机会,一旦设置成功,在这个配置纪元里面就不能更改
  • 每个发现主服务器进入客观下线的Sentinel都会要求其他Sentinel将自己设为局部领头Sentinel
  • 当一个Sentinel(源)向另一个Sentinel(目标)发送SENTINEL命令,命令中runid参数不是*符号,而是源Sentinel运行ID时,表示源Sentinel要求目标Sentinel将源Sentinel设置为局部领头Sentinel
  • Sentinel设置局部领头Sentinel的规则是先到先得,后接收的请求都会被拒绝
  • 目标Sentinel的接收到SENTINEL命令的回复,leader_runid和leader_epoch记录了目标Sentinel的局部领头Sentinel的运行ID和配置纪元
  • 某个Sentinel被半数以上的Sentinel设置为局部领头Sentinel,那么这个Sentinel成为领头Sentinel
  • 如果给定时限内,没有选举成功。那么将在一段时间之后再次进行选举,直到选出为止。

故障转移

选出新的主服务器

  1. 删除所有处于下线或者断线状态的从服务器
  2. 删除列表中所有最近五秒内没有回复过领头Sentinel的INFO命令的从服务器
  3. 删除所有与已下线主服务连接断开超过down-after-milliseconds*10毫秒的从服务器。保留保存数据比较新的服务器
  4. 根据从服务器的优先级
  5. 根据从服务器的复制偏移量
  6. 根据RunId,选择runid最小的从服务器
  7. 领头Sentinel向选中服务器发送SLAVOF no one 命令
  8. 通过Info命令确认从服务器已经升级为主服务器

            

修改从服务器的复制目标

领头Sentinel向已下线主服务器的从服务器发送SLAVEOF命令

将旧主服务器变为从服务器

当下线主服务器重新上线,发送SLAVEOF命令,让它成为从服务器。

                                   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值