redis集群管理--sentinel

集群配置:https://blog.csdn.net/macro_g/article/details/82593996

什么是sentinel?

  Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是Redis 的高可用性解决方案,sentinel哨兵模式已经被集成在redis2.4之后的版本中。sentinel是redis高可用的解决方案,sentinel系统可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。

  sentinel可以让redis实现主从复制,当一个集群中的master失效之后,sentinel可以选举出一个新的master用于自动接替master的工作,集群中的其他redis服务器自动指向新的master同步数据。一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换。其结构如下:

 

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案

  当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。Sentinel由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

 

例如下图所示:

在Server1 掉线后:

升级Server2 为新的主服务器:

Sentinel版本

  1.Sentinel当前最新的稳定版本称为Sentinel 2(与之前的Sentinel 1区分开来)。

  2.随着redis2.8的安装包一起发行。安装完Redis2.8后,可以在redis2.8/src/里面找到Redis-sentinel的启动程序。

  3.强烈建议:如果你使用的是redis2.6(sentinel版本为sentinel 1),你最好应该使用redis2.8版本的sentinel 2,因为sentinel 1有很多的Bug,已经被官方弃用,所以强烈建议使用redis2.8以及sentinel 2。

Sentinel状态持久化

  1.snetinel的状态会被持久化地写入sentinel的配置文件中。

  2.每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。

  3.这意味着,可以安全的停止和重启sentinel进程。

Sentinel作用:

  1)Master状态检测

  2)如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave。

  3)Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。

Sentinel工作方式(每个Sentinel实例都执行的定时任务)

  1)每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个PING命令。

  2)如果一个实例(instance)距离最后一次有效回复PING命令的时间超过 own-after-milliseconds 选项所指定的值,则这个实例会被Sentinel标记为主观下线。

  3)如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。

  4)当有足够数量的Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线。

  5)在一般情况下,每个Sentinel 会以每10秒一次的频率向它已知的所有Master,Slave发送 INFO 命令。

  6)当Master被Sentinel标记为客观下线时,Sentinel 向下线的 Master 的所有Slave发送 INFO命令的频率会从10秒一次改为每秒一次。

  7)若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。 若 Master重新向Sentinel 的PING命令返回有效回复,Master的主观下线状态就会被移除。

三个定时任务

  sentinel在内部有3个定时任务

    1)每10秒每个sentinel会对master和slave执行info命令,这个任务达到两个目的:

      a)发现slave节点

      b)确认主从关系

    2)每2秒每个sentinel通过master节点的channel交换信息(pub/sub)。master节点上有一个发布订阅的频道(sentinel:hello)。sentinel节点通过sentinel:hello频道进行信息交换(对节点的"看法"和自身的信息),达成共识。

    3)每1秒每个sentinel对其他sentinel和redis节点执行ping操作(相互监控),这个其实是一个心跳检测,是失败判定的依据。

 

主观下线

  1.所谓主观下线(Subjectively Down, 简称 SDOWN)指的是单个Sentinel实例对服务器做出的下线判断,即单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。

  2.主观下线就是说如果服务器在down-after-milliseconds给定的毫秒数之内, 没有返回 Sentinel 发送的 PING 命令的回复, 或者返回一个错误, 那么 Sentinel 将这个服务器标记为主观下线(SDOWN )。

  3.sentinel会以每秒一次的频率向所有与其建立了命令连接的实例(master,从服务,其他sentinel)发ping命令,通过判断ping回复是有效回复,还是无效回复来判断实例时候在线(对该sentinel来说是“主观在线”)。 sentinel配置文件中的down-after-milliseconds设置了判断主观下线的时间长度,如果实例在down-after-milliseconds毫秒内,返回的都是无效回复,那么sentinel回认为该实例已(主观)下线,修改其flags状态为SRI_S_DOWN。如果多个sentinel监视一个服务,有可能存在多个sentinel的down-after-milliseconds配置不同,这个在实际生产中要注意。

客观下线

 客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断,然后开启failover。 客观下线就是说只有在足够数量的 Sentinel 都将一个服务器标记为主观下线之后, 服务器才会被标记为客观下线(ODOWN)。 只有当master被认定为客观下线时,才会发生故障迁移。 当sentinel监视的某个服务主观下线后,sentinel会询问其它监视该服务的sentinel,看它们是否也认为该服务主观下线,接收到足够数量(这个值可以配置)的sentinel判断为主观下线,既任务该服务客观下线,并对其做故障转移操作。 sentinel通过发送 SENTINEL is-master-down-by-addr ip port current_epoch runid,(ip:主观下线的服务id,port:主观下线的服务端口,current_epoch:sentinel的纪元,runid:*表示检测服务下线状态,如果是sentinel 运行id,表示用来选举领头sentinel)来询问其它sentinel是否同意服务下线。 一个sentinel接收另一个sentinel发来的is-master-down-by-addr后,提取参数,根据ip和端口,检测该服务时候在该sentinel主观下线,并且回复is-master-down-by-addr,回复包含三个参数:down_state(1表示已下线,0表示未下线),leader_runid(领头sentinal id),leader_epoch(领头sentinel纪元)。 sentinel接收到回复后,根据配置设置的下线最小数量,达到这个值,既认为该服务客观下线。 客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例, Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。只要一个 Sentinel 发现某个主服务器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障迁移操作。

 

在redis-sentinel的conf文件里有这么两个配置:

 1)sentinel monitor

  四个参数含义:

    a)、masterName这个是对某个master+slave组合的一个区分标识(一套sentinel是可以监听多套master+slave这样的组合的)。

    b)、ip 和 port 就是master节点的 ip 和 端口号。 quorum这个参数是进行客观下线的一个依据,意思是至少有 quorum 个sentinel主观的认为这个master有故障,才会对这个master进行下线以及故障转移。

    c)、有的时候,某个sentinel节点可能因为自身网络原因,导致无法连接master,而此时master并没有出现故障,所以这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。

 2)sentinel down-after-milliseconds

  1.这个配置其实就是进行主观下线的一个依据

  2.masterName这个参数不用说了,timeout是一个毫秒值,表示:如果这台sentinel超过timeout这个时间都无法连通master包括slave(slave不需要客观下线,因为不需要故障转移)的话,就会主观认为该master已经下线(实际下线需要客观下线的判断通过才会下线)

多个sentinel之间是如何达到共识的呢?

  1.依赖于前面说的第二个定时任务,某个sentinel先将master节点进行一个主观下线,

  2.然后会将这个判定通过sentinel is-master-down-by-addr这个命令问对应的节点是否也同样认为该addr的master节点要做客观下线。

  3.当达成这一共识的sentinel个数达到前面说的quorum设置的这个值时,就会对该master节点下线进行故障转移。

  4.quorum的值一般设置为sentinel个数的二分之一加1,例如3个sentinel就设置2。

主观下线(SDOWN)和客观下线(ODOWN)的更多细节

  sentinel对于不可用有两种不同的看法,一个叫主观不可用(SDOWN),另外一个叫客观不可用(ODOWN)

    1.SDOWN是sentinel自己主观上检测到的关于master的状态,

    2.ODOWN需要一定数量的sentinel达成一致意见才能认为一个master客观上已经宕掉,

    3.各个sentinel之间通过命令SENTINEL is_master_down_by_addr来获得其它sentinel对master的检测结果。

    4.从sentinel的角度来看,如果发送了PING心跳后,在一定时间内没有收到合法的回复,就达到了SDOWN的条件。

    5.这个时间在配置中通过is-master-down-after-milliseconds参数配置。 当sentinel发送PING后,以下回复之一都被认为是合法的: PING replied with +PONG. PING replied with -LOADING error. PING replied with -MASTERDOWN error. 其它任何回复(或者根本没有回复)都是不合法的。

    6.从SDOWN切换到ODOWN不需要任何一致性算法,只需要一个gossip协议

    7.gossip协议:如果一个sentinel收到了足够多的sentinel发来消息告诉它某个master已经down掉了,SDOWN状态就会变成ODOWN状态。

    8.如果之后master可用了,这个状态就会相应地被清理掉。

    9.正如之前已经解释过了,真正进行failover需要一个授权的过程,但是所有的failover都开始于一个ODOWN状态。

    10.ODOWN状态只适用于master,对于不是master的redis节点sentinel之间不需要任何协商,slaves和sentinel不会有ODOWN状态。

配置版本号

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

    1.当一个sentinel被授权后,它将会获得宕掉的master的一份最新配置版本号,当failover执行结束以后,这个版本号将会被用于最新的配置。

    2.因为大多数sentinel都已经知道该版本号已经被要执行failover的sentinel拿走了,所以其他的sentinel都不能再去使用这个版本号。

    3.这意味着,每次failover都会附带有一个独一无二的版本号。我们将会看到这样做的重要性。 

    4.sentinel集群都遵守一个规则:如果sentinel A推荐sentinel B去执行failover,B会等待一段时间后,自行再次去对同一个master执行failover,这个等待的时间是通过failover-timeout配置项去配置的。    

    5.从这个规则可以看出,sentinel集群中的sentinel不会再同一时刻并发去failover同一个master,第一个进行failover的sentinel如果失败了,另外一个将会在一定时间内进行重新进行failover,

    6.redis sentinel保证了活跃性:如果大多数sentinel能够互相通信,最终将会有一个被授权去进行failover.

    7.redis sentinel也保证了安全性:每个试图去failover同一个master的sentinel都会得到一个独一无二的版本号。    

  举个例子:

    a、假设有一个名为mymaster的地址为192.168.10.202:6379。

    b、一开始,集群中所有的sentinel都知道这个地址,于是为mymaster的配置打上版本号1。

    c、一段时候后mymaster死了,有一个sentinel被授权用版本号2对其进行failover。

    d、如果failover成功了,假设地址改为了192.168.10.202:9000,此时配置的版本号为2,进行failover的sentinel会将新配置广播给其他的sentinel

    e、由于其他sentinel维护的版本号为1,发现新配置的版本号为2时,版本号变大了,说明配置更新了,于是就会采用最新的版本号为2的配置。

    f、这意味着sentinel集群保证了第二种活跃性:一个能够互相通信的sentinel集群最终会采用版本号最高且相同的配置。

sentinel的‘仲裁会’

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

  2、不过,当failover主备切换真正被触发后,failover并不会马上进行,还需要sentinel中的大多数sentinel授权后才可以进行failover。

  3、当ODOWN时,failover被触发。

  4、failover一旦被触发,尝试去进行failover的sentinel会去获得“大多数”sentinel的授权(如果票数比大多数还要大的时候,则询问更多的sentinel) 这个区别看起来很微妙,但是很容易理解和使用。

  5、例如,集群中有5个sentinel,票数被设置为2,当2个sentinel认为一个master已经不可用了以后,将会触发failover,但是,进行failover的那个sentinel必须先获得至少3个sentinel的授权才可以实行failover。 如果票数被设置为5,要达到ODOWN状态,必须所有5个sentinel都主观认为master为不可用,要进行failover,那么得获得所有5个sentinel的授权。

选取领头羊sentinel(即领导者选举)

  一个redis服务被判断为客观下线时,多个监视该服务的sentinel协商,选举一个领头sentinel,对该redis服务进行故障转移操作。

  选举领头sentinel遵循以下规则:

    1)所有的sentinel都有公平被选举成领头的资格。

    2)所有的sentinel都有且只有一次将某个sentinel选举成领头的机会(在一轮选举中),一旦选举某个sentinel为领头,不能更改。

    3)sentinel设置领头sentinel是先到先得,一旦当前sentinel设置了领头sentinel,以后要求设置sentinel为领头请求都会被拒绝。

    4)每个发现服务客观下线的sentinel,都会要求其他sentinel将自己设置成领头。

    5)当一个sentinel(源sentinel)向另一个sentinel(目sentinel)发送is-master-down-by-addr ip port current_epoch runid命令的时候,runid参数不是*,而是sentinel运行id,就表示源sentinel要求目标sentinel选举其为领头。

    6)源sentinel会检查目标sentinel对其要求设置成领头的回复,如果回复的leader_runid和leader_epoch为源sentinel,表示目标sentinel同意将源sentinel设置成领头。

    7)如果某个sentinel被半数以上的sentinel设置成领头,那么该sentinel既为领头。

    8)如果在限定时间内,没有选举出领头sentinel,暂定一段时间,再选举。

  为什么要选领导者?

    简单来说,就是因为只能有一个sentinel节点去完成故障转移。 sentinel is-master-down-by-addr这个命令有两个作用,

      一、是确认下线判定,

      二、是进行领导者选举。

  选举过程:

    1)每个做主观下线的sentinel节点向其他sentinel节点发送上面那条命令,要求将它设置为领导者。

    2)收到命令的sentinel节点如果还没有同意过其他的sentinel发送的命令(还未投过票),那么就会同意,否则拒绝。

    3)如果该sentinel节点发现自己的票数已经过半且达到了quorum的值,就会成为领导者

    4)如果这个过程出现多个sentinel成为领导者,则会等待一段时间重新选举。

redis sentinel的主从切换方案

  Redis 2.8版开始正式提供名为Sentinel的主从切换方案,通俗的来讲,Sentinel可以用来管理多个Redis服务器实例,可以实现一个功能上实现HA的集群

  Sentinel主要负责三个方面的任务

    1)监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

    2)提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

    3)自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

 

Sentinel集群

  Redis Sentinel 是一个分布式系统, 可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。 一个简单的主从结构加sentinel集群的架构图如下:

 

 

  1、上图是一主一从节点,加上两个部署了sentinel的集群,

  2、sentinel集群之间会互相通信,沟通交流redis节点的状态,做出相应的判断并进行处理,

  3、这里的主观下线状态和客观下线状态是比较重要的状态,它们决定了是否进行故障转移

  4、可以通过订阅指定的频道信息,当服务器出现故障得时候通知管理员

  5、客户端可以将 Sentinel 看作是一个只提供了订阅功能的 Redis 服务器,你不可以使用 PUBLISH 命令向这个服务器发送信息,但你可以用 SUBSCRIBE 命令或者 PSUBSCRIBE 命令,通过订阅给定的频道来获取相应的事件提醒。

  6、一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。

  7、个人认为,Sentinel实现的最主要的一个功能就是能做到自动故障迁移,即当某一个master挂了的时候,可以自动的将某一个slave提升为新的master,且原master的所有slave也都自动的将自己的master改为新提升的master,这样我们的程序的可用性大大提高了。只要redis安装完成,Sentinel就安装完成了,Sentinel集成在redis里了。

为什么sentinel有集群方案?

  1、只使用单个sentinel进程来监控redis集群是不可靠的,

  2、当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。

  3、所以有必要将sentinel集群

  (可以部署在多台机器上,也可以在一台物理机上通过多端口实现伪集群部署)

  集群的好处:

     1)即使有一些sentinel进程宕掉了,依然可以进行redis集群的主备切换;

    2)如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);

    3)如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息。

sentinel集群注意事项

  1)只有Sentinel 集群中大多数服务器认定master主观下线时master才会被认定为客观下线,才可以进行故障迁移,也就是说,即使不管我们在sentinel monitor中设置的数是多少,就算是满足了该值,只要达不到大多数,就不会发生故障迁移。

  2)官方建议sentinel至少部署三台,且分布在不同机器。这里主要考虑到sentinel的可用性,假如我们只部署了两台sentinel,且quorum设置为1,也可以实现自动故障迁移,但假如其中一台sentinel挂了,就永远不会触发自动故障迁移,因为永远达不到大多数sentinel认定master主观下线了。

  3)sentinel monitor配置中的master IP尽量不要写127.0.0.1或localhost,因为客户端,如jedis获取master是根据这个获取的,若这样配置,jedis获取的ip则是127.0.0.1,这样就可能导致程序连接不上master

  4)当sentinel 启动后会自动的修改sentinel.conf文件,如已发现的master的slave信息,和集群中其它sentinel 的信息等,这样即使重启sentinel也能保持原来的状态。注意,当集群服务器调整时,如更换sentinel的机器,或者新配置一个sentinel,请不要直接复制原来运行过得sentinel配置文件,因为其里面自动生成了以上说的那些信息,我们应该复制一个新的配置文件或者把自动生成的信息给删掉。

  5)当发生故障迁移的时候,master的变更记录与slave更换master的修改会自动同步到redis的配置文件,这样即使重启redis也能保持变更后的状态。

 

posted @ 2020-05-25 15:03  X小白的逆袭之旅  阅读(557)  评论(0编辑  收藏  举报