sentinel是redis的高可用性解决方案:由一个或多个sentinel实例组成sentinel系统监视多个master以及master的slave,并在被监视的master进入下线状态时,自动将下线master的某个slave升级为master,然后新的master代替下线的master处
理命令请求。
一、下线状态监测
(1)、主观下线监测
在默认情况下,sentinel会以每秒一次的频率向所有与它创建了命令连接的实例(master、slave、sentinel)发送ping,如果实例在down_after_period时间内,没有返回正确回复,标记为SRI_S_DOWN,反之,标记为正常状态。
由定时任务serverCron定期监听所有连接实例
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
……
run_with_period(100) {
//如果是哨兵服务器,触发sentinelTimer
if (server.sentinel_mode) sentinelTimer();
}
……
}
void sentinelTimer(void) {
……
sentinelHandleDictOfRedisInstances(sentinel.masters);
……
}//检查所有连接实例
void sentinelHandleDictOfRedisInstances(dict *instances) {
……//instances为sentinelState->masters
while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de);
sentinelHandleRedisInstance(ri);
if (ri->flags & SRI_MASTER) {
sentinelHandleDictOfRedisInstances(ri->slaves);
sentinelHandleDictOfRedisInstances(ri->sentinels);
……
}
}
}
……
}
void sentinelHandleRedisInstance(sentinelRedisInstance *ri) {
……//发送ping给这个实例
sentinelSendPeriodicCommands(ri);
//检查是否主观下线
sentinelCheckSubjectivelyDown(ri);
……
}//主观下线检查
void sentinelCheckSubjectivelyDown(sentinelRedisInstance *ri) {
mstime_t elapsed = 0;
//收到pong后,act_ping_time会被置为0
if (ri->link->act_ping_time)
elapsed = mstime() - ri->link->act_ping_time;
if (elapsed > ri->down_after_period ||
(ri->flags & SRI_MASTER &&ri->role_reported == SRI_SLAVE &&
mstime() - ri->role_reported_time >
(ri->down_after_period+SENTINEL_INFO_PERIOD*2)))
{//实例之前不是下线状态,更新为下线状态同时更新下线时间
if ((ri->flags & SRI_S_DOWN) == 0) {
ri->s_down_since_time = mstime();
ri->flags |= SRI_S_DOWN;
}
} else