【Redis】哨兵模式

纸上得来终觉浅,绝知此事要躬行。html

哨兵模式

Sentinel是Redis的高可用的解决方案,有多个Sentinel实例构成Sentinel系统。系统能够监视任意多个主服务器以及这些主服务器下的从服务器,当被监视的主服务器进入下线状态时,自动将下线的主服务属下的从服务器升级为新的主服务器,而后由新的主服务器替代下线主服务器继续处理命令请求。redis

下图展现了一个Sentinel系统监视服务器的例子:sql

Sentinel系统监视服务器

假设此时,主服务器Master因为某种缘由意外宕机下线,那么从服务器slave对主服务器的复制操做将被终止。而且Sentinel系统会察觉到Master已经下线。服务器

Master宕机

当Master长时间处于下线,Sentinel系统将会对Master进行执行故障转移,以后Sentinel系统会在Master属下的从服务器挑选出一个做为新的主服务器,而且先其余slave发送复制指令,让他们重新的服务器开始复制。网络

当某个时间旧Master从新上线时,Sentinel系统会将它设置为新服务器的从服务器。异步

Master从新上线

注意:以上的Sentinel系统中任意一台Sentinel都会监视全部的服务器3d

启动 Sentinel

  • 对于 redis-sentinel 程序, 你能够用如下命令来启动 Sentinel 系统:
redis-sentinel /path/to/sentinel.conf
  • 对于 redis-server 程序, 你能够用如下命令来启动一个运行在 Sentinel 模式下的 Redis 服务器:
redis-server /path/to/sentinel.conf --sentinel

配置Sentinel

配置项 示例 说明
sentinel auth-pass
<服务器名称>
sentinel auth-pass mymaster
ydongy
链接服务器口令
sentinel down-after-milliseconds
<自定义服务名称><主机地址><端口><主从服务器总量>
sentinel monitor mymaster
1127.0.0.1 6379 1
设置哨兵监听的主服务器信息,最后的参数决定了最终参与选举的服务器数量
sentinel parallel-syncs
<服务名称><服务器数(整数)>
sentinel parallel-syncs
mymaster 1
指定同时进行主从的slave数量,数值越大,要求网络资源越高,要求约小,同步时间约长
sentinel failover-timeout
<服务名称><毫秒数(整数)>
sentinel failover-timeout
mymaster 9000
指定出现故障后,故障切换的最大超时时间,超过该值,认定切换失败,默认3分钟
sentinel notification-script
<服务名称><脚本路径>
服务器没法正常联通时,设定的执行脚本,一般调试使用。

工做原理

1. 创建与服务器之间的链接

Sentinel启动时会经过配置建立与指定主服务器的网络链接,Sentinel将成为主服务器的客户端,能够向主服务器发送命令,而且从命令的回复中获取相关服务器的信息。调试

对于每一个被Sentinel监视和主服务器来讲,Sentinel会建立两个异步网络链接:code

  • 命令链接:专门发送命令给主服务器
  • 订阅链接:专门订阅主服务器的__Sentinel__:hello频道

Sentinel默认会每十秒发送一次info命令,经过分析info命令的回复获取主服务器当前信息以及根据当前主服务器下的从服务器ipport地址信息,自动的发现从服务器。并保存在一个键为:ip:port,值为从服务器的实例结构的字典当中。一样也会建立链接到从服务器的命令链接和订阅链接。整个结构以下图:server

在建立命令以后,Sentinel在默认状况下,一样也会每十秒一次的频率经过命令链接向从服务器发送info命令,得到从服务器的详细信息,根据这些信息,会对以前的从服务器实例结构进行更新。

2. 发送消息

在默认状况下,Sentinel会以每两秒一次的频率,经过命令链接向全部被监视的主服务器和从服务器发送命令到__Sentinel__:hello频道:

PUBLISH __Sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"
  • s_表示Sentinel自己信息
  • m_表示主服务的信息

经过命令链接__Sentinel__:hello频道发送的消息,同时又会被订阅链接从频道中获取出来,包括其余在__Sentinel__:hello频道中的Sentinel一样也会接受到该信息(包括发送者本身)。举个例子,以下图:

因为每一个Sentinel都会发送消息,也就是说任何一个Sentinel都会接受到本身以及其余Sentinel发送的消息,而且消息中含有Sentinel的信息,因此每一个Sentinel都会把本身以及其余的Sentinel的信息保存在字典当中,键是ip:port,值是一个Sentinel实例结构。当之后每次接受到消息,更新保存的信息,防止有宕机的Sentinel或者新添加的Sentinel。

3. 建立与其余Sentinel的命令链接

上一节说了在Sentinel向服务器经过命令链接发送信息,会被订阅链接接受到消息,若是发现一个字典当中不存在当前Sentinel,会为当前Sentinel建立相应的实例结构。

其实,同时会建立一个命令链接,而新Sentinel也会链接到这个Sentinel,至关于两两相连,以下图所示:

4. 主观下线

在默认状况下,Sentinel会一秒一次的频率向全部与它建立命令链接的服务器(包括:主服务器,从服务器,其余Sentinel)发送PING命令,经过实例的返回恢复来判断实例时候在线。

发送PING命令回复分为两种:

  • 有效恢复:
    • +PONG
    • -LOADING
    • -MASTERDOWN
  • 无效恢复:不包含以上三种,或者返回其余恢复

最开始启动Sentinel的时候,咱们在配置文件中配置了一个down-after-milliseconds的参数,若是在当前参数范围内没有一次有效恢复,那么当前Sentinel就认为该服务器主观下线,固然还可能存在多个Sentinel配置的时间大小不一样,例如:

  • Sentinel-1
sentinel monitor master 127.0.0.1 6379 2
sentinel down-after-milliseconds master 60000
  • Sentinel-2
sentinel monitor master 127.0.0.1 6379 2
sentinel down-after-milliseconds master 20000

那么当master的断线时长超过20000毫秒以后,sentinel-2会判断该服务器主观下线,可是Sentinel-1认为master处于在线状态,以后当master断线60000毫秒以后,Sentinel-1和Sentinel-2才都会认为master进入主观下线状态。结合图查看一下:

5. 客观下线

当Sentinel将一个主服务器判断为主观下线以后,为了确保主服务器真正的下线,当前的Sentinel会先其余监视该服务器的Sentinel进行询问,看他们是否也认为主服务器进入下线状态,当Sentinel从其余Sentinel哪里接受到足够数量的如下线判断以后,Sentinel就会将服务断定为客观下线,以后便进行故障转移。

经过发送以下命令进行询问其余Sentinel:

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>
  • ip:主服务器IP地址
  • port:主服务器端口号
  • current_epoch:Sentinel当前的配置纪元
  • runid:能够为*表示仅仅检测主服务器的客观下线状态,或者是Sentinel的运行ID用于选举领头Sentinel

接受源Sentinel命令回复:

  • down_state:返回接受者Sentinel的对主服务器的检查结果,1:下线,0:未下线
  • leader_runid:能够是*表示仅仅检测主服务器的下线状态,或者接受者Sentinel的运行ID用于选举领头Sentinel
  • leader_epoch:接受者Sentinel的认为领头Sentinel的配置纪元

例如:

1
*
0

那么说明接受者Sentinel也赞成主服务已下线。整个过程如图所示:

客观下线的判断条件是经过配置中sentinel monitor host6379 127.0.0.1 6379 2最后一个参数决定,例如当前为2,意味着若是全部的Sentinel只要有两个认为主服务器下线,那么当前Sentinel才会将主服务判断为客观下线。

5. 选举领头Sentinel

在一个主服务器被判断为客观下线时,监视这个下线主服务器的一个Sentinel会进行协商,选出一个领头Sentinel去进行故障转移操做。

选取领头Sentinel规则和方法:

  • 任意一个Sentinel都有可能
  • 经过相似投票的方式,其实内部就是经过上面提到的回复leader_epoch,若是接受者Sentinel回复的参数是发送者Sentinel的运行ID,就代表当前Sentinel投给了发送者Sentinel这一票,只要有一个Sentinel的票数大于总票的一半以上,那么那个Sentinel就会成为领头Sentinel
  • 若是规定时间没有选出,那么在一段时间以后会再次进行选举,直到选出为止

6. 故障转移

在选举出领头Sentinel以后,领头Sentinel将对已下线的主服务器执行故障转移操做,包含如下步骤:

  1. 在主服务器属下的从服务器选择一个,转换为主服务器
  2. 让其余从服务器改成复制新的主服务器
  3. 将已经下线的服务器设置为新的主服务器的从服务器,一旦旧服务器上线以后,自动链接成为新服务器的从服务器

从服务器挑选规则:将全部从服务器保存到一个列表,对列表进行过滤:

  1. 删除列表中下线或断线的
  2. 最近5秒没有回复过领头Sentinel的info命令的
  3. 删除与主服务器断开链接过长的
  4. 根据从服务器优先级排序,选择优先级高的
  5. 优先级相同,按照复制的偏移量大小排序,选出偏移量最大的。偏移量大意味着保存的是最新的数据,
  6. 若是还存在多个,按照运行ID排序,选出运行ID最小的

选出以后发送命令sqlveof no one,而后接着每秒一次发送info命令,分析回复信息,直到被选中的从服务器的rolemaster,表示成功升级为主服务器。以后修改其余从服务器的复制目标,发送命令slaveof ip port(ip是升级后的服务器ip,port是升级后服务器的port)。

当旧服务器从新上线,Sentinel会向它发送slaveof命令,让他成* 为新的主服务器的从服务器。

Sentinel案例

sentinel-1 sentinel-2 sentinel-3
port 26379
sentinel monitor host6379 127.0.0.1 6379 2
sentinel down-after-milliseconds host6379 60000
sentinel failover-timeout host6379 180000
sentinel parallel-syncs host6379 1
port 26380
sentinel monitor host6379 127.0.0.1 6379 2
sentinel down-after-milliseconds host6379 60000
sentinel failover-timeout host6379 180000
sentinel parallel-syncs host6379 1
port 26381
sentinel monitor host6379 127.0.0.1 6379 2
sentinel down-after-milliseconds host6379 60000
sentinel failover-timeout host6379 180000
sentinel parallel-syncs host6379 1
  • port:配置哨兵端口

  • sentinel monitor host6379 127.0.0.1 6379 2:指示 Sentinel 去监视一个名为 mymaster 的主服务器, 这个主服务器的 IP 地址为 127.0.0.1 , 端口号为 6379 , 而将这个主服务器判断为失效至少须要 2 个 Sentinel 赞成 (只要赞成 Sentinel 的数量不达标,自动故障迁移就不会执行)。

  • down-after-milliseconds :选项指定了 Sentinel 认为服务器host6379已经断线所需的毫秒数。若是服务器在给定的毫秒数以内, 没有返回 Sentinel 发送的 PING 命令的回复, 或者返回一个错误, 那么 Sentinel 将这个服务器标记为主观下线。 只有在足够数量的 Sentinel 都将一个服务器标记为主观下线以后, 服务器才会被标记为客观下线,这时自动故障迁移才会执行。

    • 服务器对 PING 命令的有效回复能够是如下三种回复的其中一种:

      • 返回 +PONG 。
      • 返回 -LOADING 错误。
      • 返回 -MASTERDOWN 错误。

    若是服务器返回除以上三种回复以外的其余回复, 又或者在指定时间内没有回复 PING 命令, 那么 Sentinel 认为服务器返回的回复无效(non-valid)。

    注意, 一个服务器必须在 master-down-after-milliseconds 毫秒内, 一直返回无效回复才会被 Sentinel 标记为主观下线

    举个例子, 若是 master-down-after-milliseconds 选项的值为 30000 毫秒(30 秒), 那么只要服务器能在每 29 秒以内返回至少一次有效回复, 这个服务器就仍然会被认为是处于正常状态的。

  • parallel-syncs: 选项指定了在执行故障转移时, 最多能够有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长。

参考链接:
http://www.redis.cn/topics/sentinel.html

相关文章
相关标签/搜索