一,哨兵模式的简介
1,哨兵模式的作用
sentinel是redis实现高可用性的解决方案;有一个或者多个sentinel组成的sentinel系统,会监控主服务器及其下属的从服务器,当监视的主服务器进入下线状态,那么sentinel就会使得从服务器代替主服务器,继续处理客户端发来的写命令;
2,故障转移操作
情况:A为主服务器,B,C,D为从服务器;
a,当A服务器挂了之后,那么sentinel会从B,C,D中挑选一个服务器来作为主服务器,代替A;
b,使得其他从服务器重新新的主服务器,此时故障转移操作完毕;
c,sentinel还会继续监视A服务器,当服务器再次上线之后,就会将A服务器设置为从服务器然后关联现在主服务器;
一,启动并初始化sentinel
1,启动sentinel命令
a,redis-sentinel /path/to/your/sentinel.conf
b,redis-server /path/to/you/sentinel.conf --sentinel
2,启动一个sentinel需要执行的操作
a,初始化服务器;
b,将普通redis服务器使用的代码替换成sentinel专用的代码
c,初始化sentinel状态
d,根据给定的配置文件,初始化sentinel的监视主服务器列表;
e,创建连向主服务器的网络连接
3,初始化服务器
a,解释:因为sentinel本质上是一个运行在特殊模式下的的redis服务器,因此第一步就是初始化服务器;
b,区别:因为sentinel执行的工作和普通redis是不一样的,因此初始化的时候,有些地方有区别;比如:sentinel不会加载rdb文件或者aof文件
4,使用sentinel专用代码
a,解释:因为sentinel做的工作和普通redis做的工作是不一样的,因此会使用专用的代码
b,举例:使用的端口号不同;加载的命令列表也不同;
5,初始化sentinel状态
a,解释:会初始化一个sentinelState类,这个类中保存了所有和sentinel功能相关的状态;
b,sentinelsState的结构
6,初始化sentinelState中的masters属性
a,masters属性的作用:记录了所有被sentinel监控的服务器相关信息,其中键是被监视主服务器的名字,值是服务器对应的sentinelRedisInstance结构;
b,举例:对于sentinel的初始化,将会引发对masters属性的初始化,而masters的初始化是根据载入的sentinel配置文件进行的;
c,sentinelRedisInstance结构
d,masters属性初始化之后
7,创建连向主服务器的网络连接
a,连接类型:对于每个被sentinel所监视的服务器都会创建两个异步网络连接
命令连接:用于向主服务器发送命令,并接受命令回复;
订阅连接:用于订阅主服务器_sentinel_:hello频道;
b,使用两个连接的原因:
在目前redis的发布与订阅功能中,redis服务器是不会存储被发送的信息,也就是说,当服务器发送了信息之后,如果客户端处于断线中,那么发送客户端的这条消息就会丢失这条信息;因此基于这种考虑创建了一个订阅连接,专门用于订阅服务器的_sintinel_:hello频道发送的消息;
c,sentinel向主服务器创建的网路连接
二,获取主服务器信息
1,sentinel获取的信息的操作
sentinel会以默认每10秒一次的频率,通过命令连接向主服务器发送INFO命令,然后分析服务器传回的信息,来获取服务器的状态;
2,信息分析
a,主服务器的runID:
b,role:表示服务器的角色,是master还是slave
c,从服务器的信息:
3,信息分析之后做的操作
跟新sentinelRedisInstance结构中:更新runid,更新role角色,更新slave属性;
三,获取从服务器信息
1,sentinel对于从服务器的操作
当sentinel发现主服务器下的从服务器时,不仅会创建sentinelRedisInstance结构,还会创建连向从服务器的命令和订阅连接;
然后,也会以默认每10秒一次的频率发送INFO命令,获取从服务器的信息,然后用于更新sentinelRedisInstance结构
2,举例
a,建立两个连接
b,更新sentinelRedisInstance结构
四,向主服务器和从服务器发送信息
1,sentinel向主从服务器发送信息的方式和内容
sentinel会以每2秒一次的频率向主从服务器发送信息,通过命令连接,发送如下的信息:包含了sentinel的信息和主服务器的信息,其中s开头代表sentinel,m开头代表主服务器
五,接受来自主从服务器的频道信息
1,接收信息之后做的事情
当一个sentinel向主从服务器的_sentinel_:hello频道发送信息,那么主从服务器就会通过该频道在发送信息给订阅了该频道的sentinel,然后其他的sentinel在拿到该信息的时候就会更新对其他sentinel的认知以及服务器的认知;
2,更新sentinels字典
sentinel为主服务器创建的sentinelRedisInstance结构中的sentinels属性保存了sentinel本身之外所有同样监视这个主服务器的其他sentinel的信息;
3,创建连向其他sentinel的命令连接
当sentinel检测到其他的sentinel的时候,不仅会更新sentinels属性,还会创建命令连接,连向其他的sentinel,其他的sentinel也会创建同样的命令连接,连接新发现的sentinel;如下所示:
六,检测主观下线状态
1,检测操作
sentinel会默认以每秒一次的频率向主服务器,从服务器,其他的sentinel发送ping命令,并通过返回的ping命令,来判断实例是否在线;
2,命令回复内容
a,有效回复:实力返回+pong,-loading,-masterdown三种回复的其中一种;
b,无效回复:除了上述三种回复外的其他回复,都属于无效回复;
3,决定主观下线的参数
sentinel配置文件有一个down_after_milliseconds选项制定了sentinel实例判断实例进入主观下线需要的时间,如:down_after_milliseconds=5000,也就是当5000毫秒之内,sentinel实例收到的都是无效回复,那么就判断实例进入下线状态;那么sentinel实例就会将实例中flags属性中的SRI_S_DOWN打开;如下所示:
4,注意
由于每一个sentinel的after_down_milliseconds参数设置的不一样,因此这台sentinel实例认为实例已经下线,但是另一台sentinel实例不认为该实例下线了;
七,检测客观下线状态
1,做法
当sentinel实例检测到实例进入到主观下线状态,那么就会发送命令询问其他的sentinel实例,该sentinel是否下线,然后对于返回的命令进行分析,从而决定实例知否进入到客观下线装态,当进入客观下线装态,那么就会执行故障转移操作;
2,具体操作步骤
a,sentinel实例发送sentinel is-master-down-by-addr命令,如下所示:
b,sentinel接收sentinel is-master-down-by-addr命令,如下所示:
c,回复内容进行分析
sentinel实例会统计其他的sentinel实例返回的结果,当统计出超过了sentinel实例配置quorum参数的时候,那么就将实例判断为客观下线状态,然后将flags属性设置为SRI_O_DOWN;然后就会去竞选领头sentinel,当竞选成功之后,称为领头sentinel之后,才可以执行故障转移操作’;
3,不同的sentinel判断客观下线的条件可能不同
因为配置的quorum参数可能不一样,因此判断条件不一样;如quorum为2,那么当收到两个sentinel实例判定对应实例进入到主观下线状态,那么就会进入到客观下线;如quorum为5,那么需要5个,因此判断条件可能不同;
八,选举领头sentinel
1,选举过程
a,所有在线的sentinel都有被选为领头sentinel的资格;
b,每次进行领头sentinel选举之后,无论选举是否成功,所有sentinel的配置纪元的值都会自增一次;
c,在同一个配置纪元里面,所有sentinel都有一次将某个sentinel设置为局部领头sentinel机会;
d,sentinel设置局部领头sentinel的规则是先到先得
e,当一个sentinel被半数以上的sentinel设置为局部领头sentinel,那么该sentinel实例就成为领头sentinel;
f,注意:一个配置纪元里面只有一个sentinel实例被选举称为领头sentinel;如果没有选出来,那么就会在一段时间之后,进行重新选举;
九,故障转移
1,故障转移步骤
a,从已下线的主服务器的从服务器中选举出一个服务器,作为新的主服务器;
选举规则:首先根据服务器的优先级,然后根据服务器的复制偏移量,最后根据服务器的运行id,选出一个新的主服务器;
b,使得其他从服务器复制新的主服务器;可以通过向从服务器发送slaveof命令实现;
c,将就旧的主服务器变为从服务器;