其他sentinel节点接受到sentinel is-master-down-by-addr消息,调用sentinelCommand处理
void sentinelCommand(redisClient *c) {
......
//处理sentinel is-master-down-by-addr消息
} else if (!strcasecmp(c->argv[1]->ptr,"is-master-down-by-addr")) {
/* SENTINEL IS-MASTER-DOWN-BY-ADDR
*/ ...... //根据其它sentinel传送过来的消息 ri = getSentinelRedisInstanceByAddrAndRunID(sentinel.masters, c->argv[2]->ptr,port,NULL); /* It exists Is actually a master Is subjectively down It's down. * Note: if we are in tilt mode we always reply with "0". */ if (!sentinel.tilt && ri && (ri->flags & SRI_S_DOWN) && (ri->flags & SRI_MASTER)) isdown = 1; //假如发过来的信息中包含请求来源sentinel的runid,则开始进行投票 if (ri && ri->flags & SRI_MASTER && strcasecmp(c->argv[5]->ptr,"*")) { leader = sentinelVoteLeader(ri,(uint64_t)req_epoch, c->argv[5]->ptr, &leader_epoch); } //回复信息,包括isdown,leader,leader_epoch addReplyMultiBulkLen(c,3); addReply(c, isdown shared.cone : shared.czero); addReplyBulkCString(c, leader leader : "*"); addReplyLongLong(c, (long long)leader_epoch); if (leader) sdsfree(leader); }
sentinelReceiveIsMasterDownReply函数处理发送的给其他sentinel的消息”SENTINEL is-master-down-by-addr“的回复
void sentinelReceiveIsMasterDownReply(redisAsyncContext *c, void *reply, void *privdata) {
......
//根据返回值,判断是否将对应sentinel的状态置为SRI_MASTER_DOWN
if (r->element[0]->integer == 1) {
ri->flags |= SRI_MASTER_DOWN;
} else {
ri->flags &= ~SRI_MASTER_DOWN;
}
//如果sentinel返回了其选举的leader,则更新自己的leader和leader_epoch
if (strcmp(r->element[1]->str,"*")) {
sdsfree(ri->leader);
if (ri->leader_epoch != r->element[2]->integer)
redisLog(REDIS_WARNING,
"%s voted for %s %llu", ri->name,
r->element[1]->str,
(unsigned long long) r->element[2]->integer);
ri->leader = sdsnew(r->element[1]->str);
ri->leader_epoch = r->element[2]->integer;
}
}
sentinelFailoverStateMachine函数为故障转移状态机,其负责执行故障转移
void sentinelFailoverStateMachine(sentinelRedisInstance *ri) {
//master节点&正处于failover状态则继续
redisAssert(ri->flags & SRI_MASTER);
if (!(ri->flags & SRI_FAILOVER_IN_PROGRESS)) return;
switch(ri->failover_state) {
//等待故障转移开始,如果自己为leader,置状态为SENTINEL_FAILOVER_STATE_SELECT_SLAVE,开始下一步操作,否则,不变更状态,等待fail-over完成/超时
case SENTINEL_FAILOVER_STATE_WAIT_START:
sentinelFailove