Kaito
2021-09-28
1、一个哨兵检测判定主库故障,这个过程是「主观下线」,另外这个哨兵还会向其它哨兵询问(发送 sentinel is-master-down-by-addr 命令),多个哨兵都检测主库故障,数量达到配置的 quorum 值,则判定为「客观下线」 2、首先判定为客观下线的哨兵,会发起选举,让其它哨兵给自己投票成为「领导者」,成为领导者的条件是,拿到超过「半数」的确认票 + 超过预设的 quorum 阈值的赞成票 3、投票过程中会比较哨兵和主库的「纪元」(主库纪元 < 发起投票哨兵的纪元 + 发起投票哨兵的纪元 > 其它哨兵的纪元),保证一轮投票中一个哨兵只能投一次票 课后题:哨兵在 sentinelTimer 函数中调用 sentinelHandleDictOfRedisInstances 函数,对每个主节点都执行 sentinelHandleRedisInstance 函数,并且还会对主节点的所有从节点也执行 sentinelHandleRedisInstance 函数,那么,哨兵会不会判断从节点的主观下线和客观下线? sentinelHandleRedisInstance 函数逻辑如下: void sentinelHandleRedisInstance(sentinelRedisInstance *ri) { ... /* Every kind of instance */ // 判断主观下线 sentinelCheckSubjectivelyDown(ri); ... /* Only masters */ if (ri->flags & SRI_MASTER) { // 判断客观下线 sentinelCheckObjectivelyDown(ri); if (sentinelStartFailoverIfNeeded(ri)) sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_ASK_FORCED); sentinelFailoverStateMachine(ri); sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_NO_FLAGS); } } 可以看到,无论主库还是从库,哨兵都判断了「主观下线」,但只有主库才判断「客观下线」和「故障切换」。
展开
共 1 条评论
10
曾轼麟
2021-09-29
首先回到老师的问题:哨兵会判断从节点的主观下线和客观下线吗? 答:根据代码,我认为只会判断主观下线,并且在当前实例中,主观下线的slave实例是不能被选举的。 1、首先我们会发现在sentinelHandleDictOfRedisInstances函数中是存在递归调用的,当发现传入的instances是master的时候会继续对其slaves和sentinels进行递归调用,代码如下: if (ri->flags & SRI_MASTER) { //对哨兵和slaves都进行判断 sentinelHandleDictOfRedisInstances(ri->slaves); sentinelHandleDictOfRedisInstances(ri->sentinels); if (ri->failover_state == SENTINEL_FAILOVER_STATE_UPDATE_CONFIG) { switch_to_promoted = ri; } } 2、但是在调用sentinelHandleRedisInstance中的时候,只有msater才会进行【客观下线】判断,而其他实例只会进行【主观下线】判断 调用路径如下: master实例: sentinelHandleRedisInstance -> sentinelCheckSubjectivelyDown -> sentinelCheckObjectivelyDown 其它实例: sentinelHandleRedisInstance -> sentinelCheckSubjectivelyDown 在sentinelHandleRedisInstance中判断【客观下线】的代码如下所示: /* Only masters 只有master才执行 */ if (ri->flags & SRI_MASTER) { //判断客观下线 sentinelCheckObjectivelyDown(ri); if (sentinelStartFailoverIfNeeded(ri)) sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_ASK_FORCED); //调用状态机方法 sentinelFailoverStateMachine(ri); sentinelAskMasterStateToOtherSentinels(ri,SENTINEL_NO_FLAGS); } 3、已经被标记了主观下线的slave,在执行sentinelSelectSlave的时候会直接跳过,我理解是在当前投票实例的角度,如果某个slave是主观下线的,它在该实例的投票是不能参选的,当前所处的状态机状态是 SENTINEL_FAILOVER_STATE_SELECT_SLAVE。 代码如下: while((de = dictNext(di)) != NULL) { sentinelRedisInstance *slave = dictGetVal(de); mstime_t info_validity_time; //被标记主观下线或者客观下线的直接跳过 if (slave->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue; ........... instance[instances++] = slave; } ...... if (instances) { //先按照优先级排序 //如果优先级一样再按照 slave_repl_offset 来进行排序(选延迟最小的) qsort(instance,instances,sizeof(sentinelRedisInstance*), compareSlavesForPromotion); selected = instance[0]; }
展开
6
Jian
2022-03-25
硬是对了代码看了3遍才看懂:)
1
木
2023-05-30
来自广东
这里有一个很奇怪的问题,选举主节点的时候怎么能够设置2倍的配置时间呢,如果在2倍的配置时间还没有完全主从切换,又会怎么样呢
e⃰v⃰a⃰n⃰
2022-05-20
我想问假如master宕机了,直接在其他的从节点中随机一个做为主节点不就行了吗?为啥还要选举?选举也是随机啊!
共 2 条评论
Benson_Geek
2021-12-25
master 记录的 Leader 的纪元(master->leader_epoch) 求问这个到底是什么东西。。。。。。。。。。。。。。。。。。。。。。。。。救命
共 3 条评论