Redis学习笔记 - 04:Sentinel详解

Sentinel介绍

  • Redis 的主从模式下,主节点一旦发生故障不能提供服务,需要人 工干预,将从节点晋升为主节点,同时还需要修改客户端配置。 对于很多应用场景这种方式无法接受。
  • Redis 从 2.8发布了一个稳定版本的Redis Sentinel 。当前版本的 Sentinel 称为Sentinel2。它是使用更强大和更简单的预测算法来重 写初始Sentinel 实现。(Redis2.6 版本提供 Sentinel1 版本,但是有 一些问题)
  • Sentinel(哨兵)架构解决了redis主从人工干预的问题。
  • Redis Sentinel 是 redis的高可用实现方案,在实际生产环境中,对 提高整个系统可用性是非常有帮助的。

Redis Sentinel

  • Redis Sentinel 是一个分布式系统,Redis Sentinel 为 Redis 提供高可用性。可以在没有人为干预的情况下 阻止某种类型的故障。
  • 可以在一个架构中运行多个 Sentinel 进程 (progress), 这些进程使用流言协议 (gossip protocols) 来接收关于主服务器是否下线的信息,并使用投票协议 (agreement protocols) 来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。

Redis 的 Sentinel 系统用于管理多个 Redis 服务器 (instance) 该系统执行以下三个任务:

  • 监控 (Monitoring) : Sentinel 会不断地定期检查你的主服务器和从服务器是否运作正常。
  • 提醒 (Notification) : 当被监控的某个 Redis 服务器出现问题时,Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移 (Automaticfailover) : 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中 一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客 户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主 服务器代替失效服务器

Redis Sentinel 高可用性

  • 当主节点出现故障时 Redis sentinel 能自动完成故障发现和故障转移,并通知客户端从而实现真正的高可用。
  • Redis Sentinel 是一个分布式架构,其中包含N个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其他Sentinel 节点进行监控, 当它返现节点不可达时,会对节点做下线标识,如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数节点都认为主节点不可达时,会选举出一个 Sentinel 节点来完成自动故障转移的工作, 同时会将这个变化实时通知给 Redis 的客户端,整个过程是自动的不需要人工干预,有效的解决了Redis的高可用问题。

同时看出,Redis Sentinel 包含多个 Sentinel 节点,这样做带来两个好处:

  1. 对于节点的故障判断是由多个节点共同完成,这样可以有效的防止误判断
  2. 多个 Sentinel 节点出现个别节点不可用,也不会影响客户端的访问 

Redis学习笔记 - 04:Sentinel详解Sentinel 的“仲裁会”

前面我们谈到,当一个 master 被 sentinel 集群监控时,需要为它指定一个参数,这个参数指定了当需要判决 master 为不可用,并且进行 failover 时,所需要的 sentinel 数量,本文中我们暂时称这个参数为票数

不过,当 failover 主备切换真正被触发后,failover 并不会马上进行,还需要 sentinel 中的大多数 sentinel 授权后才可以进行failover。
当ODOWN时,failover 被触发。failover 一旦被触发,尝试去进行 failover 的 sentinel 会去获得“大多数” sentinel 的授权(如果票数比大多数还要大的时候,则询问更多的 sentinel)
这个区别看起来很微妙,但是很容易理解和使用。例如,集群中有5个 sentinel,票数被设置为2,当2个 sentinel 认为一个 master 已经不可用了以后,将会触发 failover,但是,进行 failover 的那个 sentinel 必须先获得至少3个 sentinel 的授权才可以实行 failover。
如果票数被设置为5,要达到ODOWN状态,必须所有5个 sentinel 都主观认为 master 为不可用,要进行 failover,那么得获得所有5个 sentinel 的授权。

配置版本号

为什么要先获得大多数 sentinel 的认可时才能真正去执行 failover 呢?

当一个 sentinel 被授权后,它将会获得宕掉的 master 的一份最新配置版本号,当 failover 执行结束以后,这个版本号将会被用于最新的配置。因为大多数 sentinel 都已经知道该版本号已经被要执行 failover 的 sentinel 拿走了,所以其他的 sentinel 都不能再去使用这个版本号。这意味着,每次 failover 都会附带有一个独一无二的版本号。我们将会看到这样做的重要性。

而且,sentinel 集群都遵守一个规则:如果 sentinel A推荐 sentinel B去执行 failover,B会等待一段时间后,自行再次去对同一个master 执行 failover,这个等待的时间是通过 failover-timeout 配置项去配置的。从这个规则可以看出,sentinel 集群中的 sentinel 不会再同一时刻并发去 failover 同一个 master,第一个进行 failover 的 sentinel 如果失败了,另外一个将会在一定时间内进行重新进行 failover,以此类推。

Redis sentinel 保证了活跃性:如果大多数 sentinel 能够互相通信,最终将会有一个被授权去进行 failover.
Redis sentinel 也保证了安全性:每个试图去 failover 同一个 master 的 sentinel 都会得到一个独一无二的版本号。

配置传播

一旦一个 sentinel 成功地对一个 master 进行了 failover,它将会把关于 master 的最新配置通过广播形式通知其它 sentinel,其它的 sentinel 则更新对应 master 的配置。
一个 faiover 要想被成功实行,sentinel 必须能够向选为 master 的 slave 发送 SLAVE OF NO ONE 命令,然后能够通过 INFO 命令看到新 master 的配置信息。
当将一个 slave 选举为 master 并发送 SLAVE OF NO ONE 后,即使其它的 slave 还没针对新 master 重新配置自己,failover 也被认为是成功了的,然后所有 sentinels 将会发布新的配置信息。
新配在集群中相互传播的方式,就是为什么我们需要当一个 sentinel 进行 failover 时必须被授权一个版本号的原因。
每个 sentinel 使用发布/订阅的方式持续地传播 master 的配置版本信息,配置传播的发布/订阅管道是:__sentinel__:hello
因为每一个配置都有一个版本号,所以以版本号最大的那个为标准。
example:假设有一个名为 mymaster 的地址为192.168.56.11:6379。一开始,集群中所有的 sentinel 都知道这个地址,于是为mymaster 的配置打上版本号1。一段时候后 mymaster 死了,有一个 sentinel 被授权用版本号2对其进行 failover。如果failover成功了,假设地址改为了192.168.56.12:6279,此时配置的版本号为2,进行 failover 的 sentinel 会将新配置广播给其他的sentinel,由于其他 sentinel 维护的版本号为1,发现新配置的版本号为2时,版本号变大了,说明配置更新了,于是就会采用最新的版本号为2的配置。
这意味着 sentinel 集群保证了第二种活跃性:一个能够互相通信的 sentinel 集群最终会采用版本号最高且相同的配置。

故障转移 

一次故障转移操作由以下步骤组成:

  1. 发现主服务器已经进入客观下线状态。
  2. 对我们的当前纪元进行自增,并尝试在这个纪元中当选。
  3. 如果当选失败,那么在设定的故障迁移超时时间的两倍之后,重新尝试当选。如果当选成功,那么执行以下步骤。
  4. 选出一个从服务器,并将它升级为主服务器。
  5. 向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
  6. 通过发布与订阅功能,将更新后的配置传播给所有其他 Sentinel,其他 Sentinel 对它们自己的配置进行更新。
  7. 向已下线主服务器的从服务器发送SLAVEOF命令,让它们去复制新的主服务器。
  8. 当所有从服务器都已经开始复制新的主服务器时,leader Sentinel 终止这次故障迁移操作。 

 每当一个 Redis 实例被重新配置(reconfigured)——无论是被设置成主服务器、从服务器、又或者被设置成其他主服务器的从服务器——Sentinel都会向被重新配置的实例发送一个CONFIG REWRITE命令,从而确保这些配置会持久化在硬盘里。

Sentinel 使用以下规则来选择新的主服务器:

  • 在失效主服务器属下的从服务器当中,那些被标记为主观下线、已断线、或者最后一次回复PING命令的时间大于五秒钟的从服务器都会被淘汰。
  • 在失效主服务器属下的从服务器当中,那些与失效主服务器连接断开的时长超过down-after选项指定的时长十倍的从服务器都会被淘汰。
  • 在经历了以上两轮淘汰之后剩下来的从服务器中,我们选出复制偏移量(replication offset)最大的那个从服务器作为新的主服务器; 如果复制偏移量不可用,或者从服务器的复制偏移量相同,那么带有最小运行ID的那个从服务器成为新的主服务器。

Sentinel状态持久化 

 sentinel 的状态会被持久化地写入 sentinel 的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。这意味着,可以安全的停止和重启 sentinel 进程。