Redis Sentinel 的一个配置陷阱

来源:互联网 发布:swf转换mp4 for mac 编辑:程序博客网 时间:2024/05/09 03:02

   Redis-sentinel是Redis实例的监控管理、通知和实例失效备援服务,是Redis集群的管理工具。在一般的分布式中心节点数据库中,Redis-sentinel的作用是中心节点的工作,监控各个其他节点的工作情况并且进行故障恢复,来提高集群的高可用性。
   Redis 2.8之后,源代码包中已包含sentinel工具,也可以用 redis-server sentinel.conf --sentinel 的方式启动。
   关于sentinel的配置参数及其原理,网上有较多的文章可参考,本文就不再重复了。
   其中有一个配置陷阱作为本文重点提一下,这个花了我一天的时间才发现并解决。
   
   计划集群环境布2台机器,组件一个 Master/Slave的REDIS主备集群(注:REDIS 3.0后可以不用Redis-sentinel组成一个分布式的集群--至少为3+3个结点)
   即然组成集群(或叫HA),那就马上想到用Redis-sentinel进行自动HA切换,考虑到硬件的可靠性,那就每台机器加一个Redis-sentinel组成2+2集群。
   即: Master1 + Slave1 + Sentinel1 + Sentinel2  四个结点
   作为集群下结点的配置,一般情况下将Sentinel1/Sentinel2两个服务的配置文件都设为相同。
   实际运行时的Sentinel1的日志如下:
[30243] 15 May 09:09:08.849 # Sentinel runid is e7d6facd50b0ac71394b872396524562cf531f29
[30243] 15 May 09:09:08.849 # +monitor master Gap4jSerialSvrMaster 10.25.0.30 7001 quorum 1
[30243] 15 May 09:09:08.866 * +slave slave 10.25.0.30:8001 10.25.0.30 8001 @ Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:09:09.911 * +sentinel sentinel 10.25.0.30:27001 10.25.0.30 27001 @ Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:09:52.102 # +sdown master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:09:52.102 # +odown master Gap4jSerialSvrMaster 10.25.0.30 7001 #quorum 1/1
[30243] 15 May 09:09:52.102 # +new-epoch 1
[30243] 15 May 09:09:52.102 # +try-failover master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:09:52.185 # +vote-for-leader e7d6facd50b0ac71394b872396524562cf531f29 1
[30243] 15 May 09:09:52.186 # 10.25.0.30:27001 voted for ef8916d373ae139b69fc7d8954b90760872b62a1 1
[30243] 15 May 09:10:02.200 # -failover-abort-not-elected master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:10:02.291 # Next failover delay: I will not start a failover before Fri May 15 09:11:52 2015
[30243] 15 May 09:11:52.189 # +new-epoch 2
[30243] 15 May 09:11:52.189 # +try-failover master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:52.374 # +vote-for-leader e7d6facd50b0ac71394b872396524562cf531f29 2
[30243] 15 May 09:11:52.452 # 10.25.0.30:27001 voted for e7d6facd50b0ac71394b872396524562cf531f29 2
[30243] 15 May 09:11:52.457 # +elected-leader master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:52.457 # +failover-state-select-slave master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:52.516 # +selected-slave slave 10.25.0.30:8001 10.25.0.30 8001 @ Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:52.516 * +failover-state-send-slaveof-noone slave 10.25.0.30:8001 10.25.0.30 8001 @ Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:52.578 * +failover-state-wait-promotion slave 10.25.0.30:8001 10.25.0.30 8001 @ Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:53.565 # +promoted-slave slave 10.25.0.30:8001 10.25.0.30 8001 @ Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:53.565 # +failover-state-reconf-slaves master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:53.566 # +failover-end master Gap4jSerialSvrMaster 10.25.0.30 7001
[30243] 15 May 09:11:53.566 # +switch-master Gap4jSerialSvrMaster 10.25.0.30 7001 10.25.0.30 8001
[30243] 15 May 09:11:53.566 * +slave slave 10.25.0.30:7001 10.25.0.30 7001 @ Gap4jSerialSvrMaster 10.25.0.30 8001
[30243] 15 May 09:12:03.635 # +sdown slave 10.25.0.30:7001 10.25.0.30 7001 @ Gap4jSerialSvrMaster 10.25.0.30 8001


  以上日志分析:
      1) 09:09:52.102 发现  7001 结点DOWN
      2) 09:09:52.102 因为有二个sentinel结点,需要进行投票选举一个sentinel主控结点
      3) 09:09:52.185 二个sentinel结点的投票结果不一致!!! -- 这就是问题
      4) 09:10:02.200 因为本次投票未产生sentinel主控结点, 下次再说,等待配置参数中的 failover-timeout 时间再投
      5) 09:11:52.374 再次选举
      6) 09:11:52.457 终于选举成功,其中一个sentinel结点得到控制权
      7) 09:11:53.566 完成切换
   
  问题:
     从发现故障,到经过二轮选举得到主控sentinel节点并完成切换,用了 2 分钟时间,故障时间过长,需要解决缩短故障解决时间。
  原因分析:     
     两个sentinel结点的关键配置项
     sentinel down-after-milliseconds Gap4jSerialSvrMaster 10000
     相同,即:10秒PING不通监控主结点认为Master异常,进入sdown(主观异常)->odown-->需要切换
     两个sentinel同个时间点发现此故障,并基本同时发投票请求给对方,结果都选自己作为sentinel主控节点,协商不成,那么留到下次再协商。
     问:下次协商就不会有这个同时投票问题了吗?
     答:一般不会,因为代码中的下次投票时间有一段:
                 master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
        即,下次时间有一定的小范围随机性,碰在一起的概率很少,只要投票有先后,那就好办了。例如:A和B说:"A作为控制结点",B只要不在同一时间也在问A,则都会同意。
  解决办法:
     两个sentinel结点的down-after-milliseconds的配置项,千万不到设置成一样,避免同时投票的冲突即可。
     例如:
     sentinel down-after-milliseconds Gap4jSerialSvrMaster 10000
     sentinel down-after-milliseconds Gap4jSerialSvrMaster 11000
  问题小结:
     sentinel的投票设计本身比较科学,但对于多个 sentinel 节点,所有的文档上都没说  down-after-milliseconds 参数建议设置为不同及其原因,实际这个碰撞问题发生又有一定的偶然性,当遇到时需要解决起来也很麻烦,往往认为是sentinel工具出问题了。       
       
      
      
      
   






0 0