redis sentinel 工作原理

Posted yangyidba

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis sentinel 工作原理相关的知识,希望对你有一定的参考价值。

一 前言

讲述了 sentinel 的安装实践和failover 切换测试,本文继续深入了解 redis sentilnel的工作原理。

二 工作原理

2.1 Sentinel 构成

一个完整的sentinel集群包括两个部分:

 
   
   
 
  1. 哨兵节点(sentinel):负责监控redissentinel节点的运行情况。

  2. 数据节点:即redis节点,包含主从节点。

2.2 Sentinel 机制

redis使用(sentinel)的工作原理是:

  1. redis使用一组sentinel节点来监控主从redis服务的可用性。

  2. 一旦监控发现redis主节点失效,将选举出一个哨兵节点作为领导者(leader)。

  3. sentinel的领导者从剩余的从redis节点中选出一个redis节点作为新的主redis节点对外服务。

我们通过几个问题来深入了解其工作机制

 
   
   
 
  1. 1 如何监控各个节点?

  2. 2 如何确定redis节点失效?

  3. 3 如何选举一个sentinel的领导者?

  4. 4 如何切换?

2.3 如何监控

sentinel节点通过三个定时监控任务监控redis节点服务可用性。

sentinel 每隔10秒向集群redis数据节点发送info命令,获取新的拓扑结构信息。包括主从角色以及ip,port。如果有新增redis节点也会自动探测到新的拓扑结构。

_sentinel_:hello频道同步信息

每个哨兵节点每隔2秒会向redis数据节点的sentinel:hello频道同步自身得到的主节点信息以及当前哨兵节点的信息,由于其他哨兵节点也订阅了这个频道,该操作可以交换哨兵节点之间关于主节点以及哨兵节点的信息。

该操作的功能有两个:

发现新的哨兵节点:如果有新的哨兵节点加入,此时保存下来这个新哨兵节点的信息,后续与该哨兵节点建立连接。

交换主节点的状态信息,作为后续客观判断主节点下线的依据。

向数据节点做心跳探测

sentinel节点每隔1秒向redis节点发送ping命令来检测实例的状态,如果在指定的时间内(down-after-milliseconds)没有回复或则返回错误的回复,那么该实例被判为下线。

这里需要特别说明两个状态SDOWN,ODOWN

主观下线 SDOWN:如果sentinel探测心跳任务在配置的down-after-milliseconds之后没有收到有效回复,那么就认为该数据节点主观下线(sdown)

客观下线 ODOWN:当一个哨兵节点认为主节点主观下线时,该哨兵节点需要通过 sentinelis-master-down-byaddr命令向其他哨兵节点咨询该主节点是否下线了,如果有超过半数的哨兵节点都回答了下线,此时认为主节点客观下线。

选举sentinel的领导者

当主节点客观下线时,需要选举出一个sentinel节点做为领导者,以完成后续选出新的主节点的工作。

 
   
   
 
  1. 每个sentinel节点通过向其他节点发送”sentinel is-master-down-by addr”命令来申请成为领导者。

  2. 而每个sentinel节点在收到一个”sentinel is-master-down-by addr”命令时,只允许给第一个节点投票,其他节点的该命令都会被拒绝。

  3. 如果一个sentinel节点收到了半数以上的同意票,则成为sentinel领导者。

  4. 如果前面三步在一定时间内都没有选出一个sentinel领导者,将重新开始下一次选举。

选择新的主节点 在剩下的redis从节点中,按照以下顺序来选择新的主节点:

 
   
   
 
  1. 过滤掉“不健康”的数据节点:比如主观下线、断线的从节点、五秒内没有回复过哨兵节点ping命令的节点、与主节点失联的从节点。

  2. 选择slave-priority(从节点优先级)最高的从节点,如果存在则返回不存在则继续后面的流程。

  3. 选择复制偏移量最大的从节点,这意味着这个从节点上面的数据最完整,如果存在则返回不存在则继续后面的流程。

  4. 到了这里,所有剩余从节点的状态都是一样的,选择runid最小的从节点。

执行failover切换

 
   
   
 
  1. sentinel向选为主节点的slave发送SLAVEOF NO ONE命令,提升该节点为主。

  2. 然后向其余redis节点发送slaveof 命令使之成为新主的从库节点。

  3. 哨兵节点集合会将原来的主节点更新为从节点,当其恢复之后命令它去复制新的主节点的数据。

因为redis采用的是异步复制,没有办法避免数据的丢失。但可以通过以下配置来使得数据不会丢失:min-slaves-to-write 1 、 min-slaves-max-lag 10。一个redis无论是master还是slave,都必须在配置中指定一个slave优先级。要注意到master也是有可能通过failover变成slave的。如果一个redis的slave优先级配置为0,那么它将永远不会被选为master,但是它依然会从master哪里复制数据。

通过上面的分析,我们已经直接回答了上面的四个问题。接下来我们根据切换日志再熟悉一下sentinel的工作流程吧。

2.4 failover 日志分析

sentinel 节点

 
   
   
 
  1. qabb-qa-mysql0 10.215.20.24 26379

  2. qabb-qa-mysql1 10.215.20.19 26379

  3. qabb-qa-mysql2 10.215.20.7 26379

redis 主从关系

 
   
   
 
  1. qabb-qa-mysql0 10.215.20.24 6379 从库

  2. qabb-qa-mysql1 10.215.20.19 6379 主库

  3. qabb-qa-mysql2 10.215.20.7 6379 从库

主动将主库关闭,观察sentinel的切换过程。

 
   
   
 
  1. 27 Jan 21:31:10.398 # +sdown master mymaster 10.215.20.19 6379 ##进入主观不可用(SDOWN)

  2. 27 Jan 21:31:10.456 # +odown master mymaster 10.215.20.19 6379 ##quorum 3/2 ##超过半数投票达到了quorum,客观不可用(ODOWN)

  3. 27 Jan 21:31:10.456 # +new-epoch 3 ##更新当前配置版本为3 ,之前切换过2次测试

  4. 27 Jan 21:31:10.456 # +try-failover master mymaster 10.215.20.19 6379 ##达到failover条件,正等待其他sentinel的选举

  5. 27 Jan 21:31:10.470 # +vote-for-leader 67b1eb6fa5fba3c927c027c1bb60b1890c23f330 3 ##投票选举

  6. 27 Jan 21:31:10.471 # b57983116e92a089ab7fff22584c1aaa128d83b8 voted for b57983116e92a089ab7fff22584c1aaa128d83b8 3 ##投票选举

  7. 27 Jan 21:31:10.488 # 966c26050372456aae216d7e5d82fff300d73c61 voted for 67b1eb6fa5fba3c927c027c1bb60b1890c23f330 3 ##投票选举

  8. 27 Jan 21:31:10.553 # +elected-leader master mymaster 10.215.20.19 6379 ##准备进行failover 切换

  9. 27 Jan 21:31:10.553 # +failover-state-select-slave master mymaster 10.215.20.19 6379

  10. 27 Jan 21:31:10.609 # +selected-slave slave 10.215.20.24:6379 10.215.20.24 6379 @ mymaster 10.215.20.19 6379 ##选择10.215.20.24为新主库

  11. 27 Jan 21:31:10.609 * +failover-state-send-slaveof-noone slave 10.215.20.24:6379 10.215.20.24 6379 @ mymaster 10.215.20.19 6379 ##执行slaveof no one

  12. 27 Jan 21:31:10.685 * +failover-state-wait-promotion slave 10.215.20.24:6379 10.215.20.24 6379 @ mymaster 10.215.20.19 6379

  13. 27 Jan 21:31:11.663 # +promoted-slave slave 10.215.20.24:6379 10.215.20.24 6379 @ mymaster 10.215.20.19 6379 ##选举为主库

  14. 27 Jan 21:31:11.663 # +failover-state-reconf-slaves master mymaster 10.215.20.19 6379 ###failover状态变为reconf-slaves

  15. ###sentinel将10.215.20.7 指向新主库

  16. 27 Jan 21:31:11.733 * +slave-reconf-sent slave 10.215.20.7:6379 10.215.20.7 6379 @ mymaster 10.215.20.19 6379

  17. 27 Jan 21:31:12.320 * +slave-reconf-inprog slave 10.215.20.7:6379 10.215.20.7 6379 @ mymaster 10.215.20.19 6379

  18. 27 Jan 21:31:12.320 * +slave-reconf-done slave 10.215.20.7:6379 10.215.20.7 6379 @ mymaster 10.215.20.19 6379

  19. ##failover成功完成

  20. 27 Jan 21:31:12.378 # +failover-end master mymaster 10.215.20.19 6379

  21. 27 Jan 21:31:12.379 * +slave slave 10.215.20.7:6379 10.215.20.7 6379 @ mymaster 10.215.20.24 6379

  22. 27 Jan 21:31:12.379 * +slave slave 10.215.20.19:6379 10.215.20.19 6379 @ mymaster 10.215.20.24 6379

  23. 27 Jan 21:31:42.476 # +sdown slave 10.215.20.19:6379 10.215.20.19 6379 @ mymaster 10.215.20.24 6379 ##原主进入主观不可用状态

从日志上可以观察到 进过 down-after-milliseconds=30000ms 也就是30秒之后老的主库进入不可用状态。如果重新启动老的主库会如下日志 ,sentinel将老的主库离开主观不可用状态,并且重新加入到主从复制关系,并指向新的主库。

 
   
   
 
  1. 27 Jan 2020 22:16:48.692 # -sdown slave 10.215.20.19:6379 10.215.20.19 6379 @ mymaster 10.215.20.24 6379

  2. 27 Jan 2020 22:16:58.631 * +convert-to-slave slave 10.215.20.19:6379 10.215.20.19 6379 @ mymaster 10.215.20.24 6379

三 小结

通过两篇文章 算是对redis sentinel 高可用机制有了深入浅出的理解和认识。另外留个尾巴业务方如何介入 redis sentinel的 ,如何做到更平滑的切换。

推荐阅读

 
   
   
 
  1. https://www.cnblogs.com/zhoujinyi/p/5570024.html


  2. https://segmentfault.com/a/1190000002680804


  3. https://www.cnblogs.com/zhoujinyi/p/5570024.html

强行结尾 祝大家身体健康,百毒不侵。。。

-The End-



以上是关于redis sentinel 工作原理的主要内容,如果未能解决你的问题,请参考以下文章

[redis 源码走读] sentinel 哨兵 - 节点发现流程

哨兵集群原理

Redis集群-哨兵模式原理(Sentinel)

Redis集群-哨兵模式原理(Sentinel)

Redis集群-哨兵模式原理(Sentinel)

Redis Sentinel实现的机制与原理详解