Redis-哨兵选出Master较慢

记录一次Redis选主慢定位过程

背景

​ 客户反馈Redis在某个场景下,选主过程会比较漫长,甚至需要超过五六分钟。Redis部署为三节点三哨兵,了解到的具体操作:1. kill 任一哨兵节点 2. 同时kill 某个哨兵和主节点 3. 重启一个哨兵节点

1. 尝试复现

​ 在跟随客户操作的工程中,发现问题复现概率较低,但所幸有成功的记录。可以在复现时,哨兵日志如下:

2322:X 31 Oct 2022 14:51:39.599 # -failover-abort-no-good-slave master mymaster 10.20.180.196 26381
2322:X 31 Oct 2022 14:51:39.671 # Next failover delay: I will not start a failover before Mon Oct 31 14:53:40 2022

​ 从语义上比较容易理解,是因为哨兵节点无法找到比较好的salve节点作为主节点但是从逻辑上理解,所有的从节点网络及状态应该都是比较健康的。

2. 定位过程

弯路

​ 既然日志都出来了,XX一下你就知道,相关的报错和解决方案倒是不少

sentinel.conf 没有设置密码

redis.conf设置了bind但是sentinel.conf没设置

其他。。你直接告诉我哨兵没连上slave就得了呗

​ 能试的该试的都试了,包括hosts、DNS、网卡配置这类网络相关的都被我研(chang)究(shi)了遍。于事无补,但是错也得试

​ 当然也并非一无所获,至少我看到了,下面这张图~~(注释是个好东西)~~

在这里插入图片描述

回头是岸

调试是不可能调试的!(关键我也不会呀,其实主要是因为一直没在自己的环境复现过,客户的我也没权限呐)

​ 其实光看这么一张图,大概只能知道一些方向,具体为什么要定位还是比较困难的,二话不说,先把对应版本的源码下载下来,根据日志信息简单搜索定位了下,代码确实如图所示。虽然看不懂那些奇怪的字母,连蒙带猜的排除了一些项,也就只有这一个条件了slave->master_link_down_time > max_master_down_time

看看这两个变量到底是干啥的

master_link_down_since_seconds

if (sdslen(l) >= 32 &&
	!memcmp(l,"master_link_down_since_seconds",30))
{
	ri->master_link_down_time = strtoll(l+31,NULL,10)*1000;
}

原来是截取salve info下master_link_down_since_seconds对应的时间*1000即salve识别到主机掉线的时间(ms)

max_master_down_time

if (!strcasecmp(argv[0],"down-after-milliseconds") && argc == 3) {
   /* down-after-milliseconds <name> <milliseconds> */
   ri = sentinelGetMasterByName(argv[1]);
   if (!ri) return "No such master with specified name.";
   ri->down_after_period = atoi(argv[2]);
   if (ri->down_after_period <= 0)
       return "negative or zero time parameter.";
   sentinelPropagateDownAfterPeriod(ri);
}
...
if (master->flags & SRI_S_DOWN)
	max_master_down_time += mstime() - master->s_down_since_time;
max_master_down_time += master->down_after_period * 10;

算了还是猜一猜这值咋来的吧,不就是配置项down-after-milliseconds

指定检测时间(毫秒)内若主节点没有应答哨兵,则哨兵节点主观上认为主节点下线。

看重点!!!

再次回忆这边的(非)变量有哪一些(翻译一下

  • salve识别到master宕掉的时间: master_link_down_time

    何时赋值:哨兵模式下,每秒会以固定频率,往服务节点发送info请求,截取master_link_down_since_seconds计算得到

  • sentinel识别到master宕掉的时间 : master->s_down_since_time

    何时赋值: 哨兵第一次识别到salve宕机的时间,深入思考下:哨兵节点在重新启动后这个值是多少

3. 水落石出

  1. 哨兵节点会定时检查Redis服务节点状态(判断是否主观掉线,同步掉线状态等)。每一次哨兵选出Master节点之前,会先投票选出哨兵的Leader节点来决定Redis的Master节点
  2. 哨兵在重启之后master->s_down_since_time重申:sentinel识别到master宕掉的时间)其实是一个非正确时间,即哨兵启动的时间
  3. 结合1,2两点,可以得出的结论是,当新启动的哨兵节点胜出为Leader节点时,因为不正确master->s_down_since_time,导致误判max_master_down_time,在符合条件if (slave->master_link_down_time > max_master_down_time) continue;后salve节点被过滤。只有当旧的哨兵被选成leader时,才能正常选出Master节点(故而选主较慢)。

4. 场景扩展与验证

​ 如果在原故障的基础上,在未选出Master节点之前,重启旧的哨兵节点,将无法选出Master节点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值