代码编织梦想

一、Redis Sentinel原理

1.1 概述

当我们部署的redis集群在运行过程中,如果主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是一个独立的进程,作为进程,它会独立运行, 它是Redis 的高可用性解决方案,可以帮助我们管理集群,哨兵,sentinel可以让redis实现主从复制,当一个集群中的master失效之后,sentinel可以选举出一个新的master用于自动接替master的工作,集群中的其他redis服务器自动指向新的master同步数据。

然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

1.2 Redis故障切换过程图示

假设主服务器宕机,哨兵1会先检测这个结果,系统不会立马进行 failover 过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象称为主观下线,当后面的哨兵检测到主服务器也不可用,并且达到一定值以后,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功以后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的

1.3 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的监控目标会随之调换。

1.4 Sentinel 工作流程

1)每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个PING命令。
2)如果一个实例(instance)距离最后一次有效回复PING命令的时间超过 down-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的主观下线状态就会被移除。

1.5 Sentinel的3个内部定时任务

1)每10s 每个Sentinel 会对master和slave执行info命令,这个任务达到两个目的: a)发现slave节点 b)确认主从关系

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

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

1.6 主观下线SDOWN

所谓主观下线(Subjectively Down, 简称 SDOWN)指的是单个Sentinel实例对服务器做出的下线判断,即单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。
主观下线就是说如果服务器在 down-after-milliseconds 给定的毫秒数之内, 没有返回 Sentinel 发送的 PING 命令的回复, 或者返回一个错误, 那么 Sentinel 将这个服务器标记为主观下线(SDOWN )。

sentinel会以每秒一次的频率向所有与其建立了命令连接的实例(master,从服务,其他sentinel)发ping命令,通过判断ping回复是有效回复,还是无效回复来判断是否在线(对该sentinel来说是“主观在线”)。

当Sentinel 发送PING后,以下回复之一都被认为是合法的:

PING replied with +PONG.
       PING replied with -LOADING error.
       PING replied with -MASTERDOWN error.
       其它任何回复(或者根本没有回复)都是不合法的。
Sentinel配置文件中的down-after-milliseconds设置了判断主观下线的时间长度,如果实例在down-after-milliseconds毫秒内,返回的都是无效回复,那么sentinel回认为该实例已(主观)下线,修改其flags状态为SRI_S_DOWN。如果多个sentinel监视一个服务,有可能存在多个sentinel的down-after-milliseconds配置不同,这个在实际生产中要注意。

1.7 客观下线ODOWN

1)概念

客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断,然后开启failover。
客观下线就是说只有在足够数量的 Sentinel 都将一个服务器标记为主观下线之后, 服务器才会被标记为客观下线(ODOWN)。只有当master被认定为客观下线时,才会发生故障迁移

2)判断过程

当前 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接收到回复后,根据配置设置的下线最小数量,判断是否达到这个值,既认为该服务是否客观下线。

如果之后master又恢复正常使用了,那么这个状态就会相应的被清理掉

3)注意事项

客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例, Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。只要一个 Sentinel 发现某个主服务器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障迁移操作

1.8 Sentinel状态持久化

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

1.9 Sentinel 如何保证failover不冲突

Sentinel 通过版本号的方式来保证

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

一个failover要想被成功实行,sentinel必须能够向选为master的slave发送SLAVEOF NO ONE命令,然后能够通过INFO命令看到新master的配置信息。当将一个slave选举为master并发送SLAVEOF NO ONE后,即使其它的slave还没针对新master重新配置自己,failover也被认为是成功了的,然后所有sentinels将会发布新的配置信息。它将会把关于master的最新配置通过广播形式通知其它sentinel,其它的sentinel则更新对应master的配置。

因为每一个配置都有一个版本号,所以以版本号最大的那个为标准。

举个例子:
假设有一个名为mymaster的地址为192.168.10.202:6379。一开始,集群中所有的sentinel都知道这个地址,于是为mymaster的配置打上版本号1。一段时候后mymaster死了,有一个sentinel被授权用版本号2对其进行failover。如果failover成功了,假设地址改为了192.168.10.202:9000,此时配置的版本号为2,进行failover的sentinel会将新配置广播给其他的sentinel,由于其他sentinel维护的版本号为1,发现新配置的版本号为2时,版本号变大了,说明配置更新了,于是就会采用最新的版本号为2的配置。

1.10 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的授权。

1.11 Sentinel的领导者选择流程

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

为什么要选领导者?
     简单来说,就是因为只能有一个sentinel节点去完成故障转移。
     sentinel is-master-down-by-addr这个命令有两个作用,一是确认下线判定,二是进行领导者选举。

选举领头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,暂定一段时间,再选举。
选举过程:
    1)每个做主观下线的sentinel节点向其他sentinel节点发送上面那条命令,要求将它设置为领导者。
    2)收到命令的sentinel节点如果还没有同意过其他的sentinel发送的命令(还未投过票),那么就会同意,否则拒绝。
    3)如果该sentinel节点发现自己的票数已经过半且达到了quorum的值,就会成为领导者
    4)如果这个过程出现多个sentinel成为领导者,则会等待一段时间重新选举。

1.12 Sentinel支持集群

只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群,这样有几个好处:
1)即使有一些sentinel进程宕掉了,依然可以进行redis集群的主备切换;
2)如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);
3)如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息。

1.13 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也能保持变更后的状态。

1.14 Sentinel之间和Slaves之间的自动发现机制

虽然sentinel集群中各个sentinel都互相连接彼此来检查对方的可用性以及互相发送消息。但是你不用在任何一个sentinel配置任何其它的sentinel的节点。因为sentinel利用了master的发布/订阅机制去自动发现其它也监控了统一master的sentinel节点。
通过向名为__sentinel__:hello的管道中发送消息来实现。
同样,你也不需要在sentinel中配置某个master的所有slave的地址,sentinel会通过询问master来得到这些slave的地址的。
每个sentinel通过向每个master和slave的发布/订阅频道__sentinel__:hello每秒发送一次消息,来宣布它的存在。
每个sentinel也订阅了每个master和slave的频道__sentinel__:hello的内容,来发现未知的sentinel,当检测到了新的sentinel,则将其加入到自身维护的master监控列表中。
每个sentinel发送的消息中也包含了其当前维护的最新的master配置。如果某个sentinel发现
自己的配置版本低于接收到的配置版本,则会用新的配置更新自己的master配置。
在为一个master添加一个新的sentinel前,sentinel总是检查是否已经有sentinel与新的sentinel的进程号或者是地址是一样的。如果是那样,这个sentinel将会被删除,而把新的sentinel添加上去。

1.15 增加或删除Sentinel

由于有sentinel自动发现机制,所以添加一个sentinel到你的集群中非常容易,你所需要做的只是监控到某个Master上,然后新添加的sentinel就能获得其他sentinel的信息以及master所有的slaves。
如果你需要添加多个sentinel,建议你一个接着一个添加,这样可以预防网络隔离带来的问题。你可以每个30秒添加一个sentinel。最后你可以用SENTINEL MASTER mastername来检查一下是否所有的sentinel都已经监控到了master。
删除一个sentinel显得有点复杂:因为sentinel永远不会删除一个已经存在过的sentinel,即使它已经与组织失去联系很久了。
要想删除一个sentinel,应该遵循如下步骤:
1)停止所要删除的sentinel
2)发送一个SENTINEL RESET * 命令给所有其它的sentinel实例,如果你想要重置指定master上面的sentinel,只需要把*号改为特定的名字,注意,需要一个接一个发,每次发送的间隔不低于30秒。
3)检查一下所有的sentinels是否都有一致的当前sentinel数。使用SENTINEL MASTER mastername 来查询。

1.16 删除旧master或者不可达slave

sentinel永远会记录好一个Master的slaves,即使slave已经与组织失联好久了。这是很有用的,因为sentinel集群必须有能力把一个恢复可用的slave进行重新配置。
并且,failover后,失效的master将会被标记为新master的一个slave,这样的话,当它变得可用时,就会从新master上复制数据。
然后,有时候你想要永久地删除掉一个slave(有可能它曾经是个master),你只需要发送一个SENTINEL RESET master命令给所有的sentinels,它们将会更新列表里能够正确地复制master数据的slave。

1.17 Slave选举与优先级

当一个sentinel准备好了要进行failover,并且收到了其他sentinel的授权,那么就需要选举出一个合适的slave来做为新的master。

slave的选举主要会评估slave的以下几个方面:
1)与master断开连接的次数
2)Slave的优先级
3)数据复制的下标(用来评估slave当前拥有多少master的数据)
4)进程ID

如果一个slave与master失去联系超过10次,并且每次都超过了配置的最大失联时间(down-after-milliseconds),如果sentinel在进行failover时发现slave失联,那么这个slave就会被sentinel认为不适合用来做新master的。
更严格的定义是,如果一个slave持续断开连接的时间超过
(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
就会被认为失去选举资格。

符合上述条件的slave才会被列入master候选人列表,并根据以下顺序来进行排序:
1)sentinel首先会根据slaves的优先级来进行排序,优先级越小排名越靠前。
2)如果优先级相同,则查看复制的下标,哪个从master接收的复制数据多,哪个就靠前。
3)如果优先级和下标都相同,就选择进程ID较小的那个。

一个redis无论是master还是slave,都必须在配置中指定一个slave优先级。要注意到master也是有可能通过failover变成slave的。
如果一个redis的slave优先级配置为0,那么它将永远不会被选为master。但是它依然会从master哪里复制数据。

1.18 故障转移

所谓故障转移就是当master宕机,选一个合适的slave来晋升为master的操作,redis-sentinel会自动完成这个,不需要我们手动来实现。

一次故障转移操作大致分为以下流程:
发现主服务器已经进入客观下线状态。
对我们的当前集群进行自增, 并尝试在这个集群中当选。
如果当选失败, 那么在设定的故障迁移超时时间的两倍之后, 重新尝试当选。 如果当选成功, 那么执行以下步骤:
选出一个从服务器,并将它升级为主服务器。
向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel , 其他 Sentinel 对它们自己的配置进行更新。
向已下线主服务器的从服务器发送 SLAVEOF 命令, 让它们去复制新的主服务器。
当所有从服务器都已经开始复制新的主服务器时, 领头 Sentinel 终止这次故障迁移操作。
每当一个 Redis 实例被重新配置(reconfigured) —— 无论是被设置成主服务器、从服务器、又或者被设置成其他主服务器的从服务器 —— Sentinel 都会向被重新配置的实例发送一个 CONFIG REWRITE 命令, 从而确保这些配置会持久化在硬盘里。

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

Sentinel 自动故障迁移的一致性特质
Sentinel 自动故障迁移使用 Raft 算法来选举领头(leader) Sentinel , 从而确保在一个给定的纪元(epoch)里, 只有一个领头产生。

这表示在同一个纪元中, 不会有两个 Sentinel 同时被选中为领头, 并且各个 Sentinel 在同一个纪元中只会对一个领头进行投票。

更高的配置纪元总是优于较低的纪元, 因此每个 Sentinel 都会主动使用更新的纪元来代替自己的配置。

简单来说, 可以将 Sentinel 配置看作是一个带有版本号的状态。 一个状态会以最后写入者胜出(last-write-wins)的方式(也即是,最新的配置总是胜出)传播至所有其他 Sentinel 。

举个例子, 当出现网络分割(network partitions)时, 一个 Sentinel 可能会包含了较旧的配置, 而当这个 Sentinel 接到其他 Sentinel 发来的版本更新的配置时, Sentinel 就会对自己的配置进行更新。

如果要在网络分割出现的情况下仍然保持一致性, 那么应该使用 min-slaves-to-write 选项, 让主服务器在连接的从实例少于给定数量时停止执行写操作, 与此同时, 应该在每个运行 Redis 主服务器或从服务器的机器上运行 Redis Sentinel 进程。

Sentinel 状态的持久化
Sentinel 的状态会被持久化在 Sentinel 配置文件里面。每当 Sentinel 接收到一个新的配置, 或者当领头 Sentinel 为主服务器创建一个新的配置时, 这个配置会与配置纪元一起被保存到磁盘里面。这意味着停止和重启 Sentinel 进程都是安全的。

Sentinel 在非故障迁移的情况下对实例进行重新配置
即使没有自动故障迁移操作在进行, Sentinel 总会尝试将当前的配置设置到被监视的实例上面。 特别是:

根据当前的配置, 如果一个从服务器被宣告为主服务器, 那么它会代替原有的主服务器, 成为新的主服务器, 并且成为原有主服务器的所有从服务器的复制对象。
那些连接了错误主服务器的从服务器会被重新配置, 使得这些从服务器会去复制正确的主服务器。
不过, 在以上这些条件满足之后, Sentinel 在对实例进行重新配置之前仍然会等待一段足够长的时间, 确保可以接收到其他 Sentinel 发来的配置更新, 从而避免自身因为保存了过期的配置而对实例进行了不必要的重新配置。

总结来说,故障转移分为三个步骤:

1)从下线的主服务的所有从服务里面挑选一个从服务,将其转成主服务
sentinel状态数据结构中保存了主服务的所有从服务信息,领头sentinel按照如下的规则从从服务列表中挑选出新的主服务;
删除列表中处于下线状态的从服务;
删除最近5秒没有回复过领头sentinel info信息的从服务;
删除与已下线的主服务断开连接时间超过 down-after-milliseconds*10毫秒的从服务,这样就能保留从的数据比较新(没有过早的与主断开连接);
领头sentinel从剩下的从列表中选择优先级高的,如果优先级一样,选择偏移量最大的(偏移量大说明复制的数据比较新),如果偏移量一样,选择运行id最小的从服务。

2)已下线主服务的所有从服务改为复制新的主服务
挑选出新的主服务之后,领头sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master。

3)将已下线的主服务设置成新的主服务的从服务,当其回复正常时,复制新的主服务,变成新的主服务的从服务
同理,当已下线的服务重新上线时,sentinel会向其发送slaveof命令,让其成为新主的从。

温馨提示:还可以向任意sentinel发生sentinel failover <masterName> 进行手动故障转移,这样就不需要经过上述主客观和选举的过程

二、Sentinel命令

2.1 登录sentinel 客户端

命令: redis-cli -h IP地址 -p 端口号

        例如:  redis-cli -h 127.0.0.1 -p 26379 

2.2 Sentinel 哨兵命令

PING :返回 PONG 。
SENTINEL masters :列出所有被监视的主服务器,以及这些主服务器的当前状态;
SENTINEL slaves <master name> :列出给定主服务器的所有从服务器,以及这些从服务器的当前状态;
SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。 如果这个主服务器正在执行故障转移操作, 或者针对这个主服务器的故障转移操作已经完成, 那么这个命令返回新的主服务器的 IP 地址和端口号;
SENTINEL reset <pattern> : 重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清楚主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel ;
SENTINEL failover <master name> : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移。 (不过发起故障转移的 Sentinel 会向其他 Sentinel 发送一个新的配置,其他 Sentinel 会根据这个配置进行相应的更新)

SENTINEL MONITOR <name> <ip> <port> <quorum> 这个命令告诉sentinel去监听一个新的master
SENTINEL REMOVE <name> 命令sentinel放弃对某个master的监听
SENTINEL SET <name> <option> <value> 这个命令很像Redis的CONFIG SET命令,用来改变指定master的配置。支持多个<option><value>。例如以下实例:SENTINEL SET objects-cache-master down-after-milliseconds 1000
只要是配置文件中存在的配置项,都可以用SENTINEL SET命令来设置。这个还可以用来设置master的属性,比如说quorum(票数),而不需要先删除master,再重新添加master。例如:SENTINEL SET objects-cache-master quorum 5

2.3 命令简单示例

[root@localhost redis-5.0.5]# redis-cli -p 26379
127.0.0.1:26379> ping
PONG
127.0.0.1:26379> sentinel masters
1)  1) "name"
    2) "master-6379"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6379"
    7) "runid"
    8) "06a057ac0d6a39e4b80c2e56e3932b76862a219e"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "430"
   19) "last-ping-reply"
   20) "430"
   21) "down-after-milliseconds"
   22) "30000"
   23) "info-refresh"
   24) "683"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "30815"
   29) "config-epoch"
   30) "2"
   31) "num-slaves"
   32) "2"
   33) "num-other-sentinels"
   34) "0"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"
127.0.0.1:26379> sentinel get-master-addr-by-name master-6379
1) "127.0.0.1"
2) "6380"

三、Sentinel 哨兵模式配置

3.1 服务器列表

节点类型

IP地址

端口

配置文件

Master主节点

192.168.146.135

6379

redis-6379.conf

Slave1 从节点

192.168.146.135

6380

redis-6380.conf

Slave2 从节点

192.168.146.135

6381

redis-6381.conf

哨兵服务1

192.168.146.135

26379

sentinel-26379.conf

哨兵服务2

192.168.146.135

26380

sentinel-26380.conf

哨兵服务3

192.168.146.135

26381

sentinel-26381.conf

3.2 搭建主从模式

可以按照我的上一篇文章搭建主从复制模式,在一台Linux虚拟机上启动3台Redis进程,需要使用3个redis.conf配置文件,主要保证其 端口号、日志文件、pidfile 、dir 等配置不同

3.3 sentinel.conf 配置文件详解

# Example sentinel.conf
 
# 哨兵sentinel实例运行的端口 默认26379
port 26379
 
# 哨兵sentinel的工作目录
dir /tmp
 
# 哨兵sentinel监控的redis主节点的 ip port 
# master-name  可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 192.168.1.108 6379 2
 
# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提供密码
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
 
 
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000
 
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,
#这个数字越小,完成failover所需的时间就越长,
#但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。
#可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
 
 
 
# 故障转移的超时时间 failover-timeout 可以用在以下这些方面: 
#1. 同一个sentinel对同一个master两次failover之间的间隔时间。
#2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
#3.当想要取消一个正在进行的failover所需要的时间。  
#4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
# 默认三分钟
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
 
# SCRIPTS EXECUTION
 
#配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。
#对于脚本的运行结果有以下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
#若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
#如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
#一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
 
#通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,
#这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,
#一个是事件的类型,
#一个是事件的描述。
#如果sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无法正常启动成功。
#通知脚本
# sentinel notification-script <master-name> <script-path>
  sentinel notification-script mymaster /var/redis/notify.sh
 
# 客户端重新配置主节点参数脚本
# 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。
# 以下参数将会在调用脚本时传给脚本:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# 目前<state>总是“failover”,
# <role>是“leader”或者“observer”中的一个。 
# 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通信的
# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
 sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

3.3 搭建哨兵Sentinel模式

1)将 redis 安装包目录的sentinel.conf 配置文件复制3份到 conf 目录下,应用于3个Sentinle哨兵

2) 配置文件修改

此处需要修改的核心配置项,主要3台的配置文件是不同的

#配置端口
port 26379
#以守护进程模式启动
daemonize yes
#日志文件名
logfile "/var/redis/logs/sentinel-26379.log"
#存放备份文件以及日志等文件的目录
dir "/var/redis/data"
#监控的IP 端口号 名称 sentinel通过投票后认为mater宕机的数量,此处为至少2个
sentinel monitor master-6379 127.0.0.1 6379 2
#Redis连接密码
sentinel auth-pass master-6379 123456
#30秒ping不同则认为宕机
sentinel down-after-milliseconds master-6379 30000
#故障转移后重新主从复制,1表示串行,>1并行
sentinel parallel-syncs master-6379 1
#故障转移开始,三分钟内没有完成,则认为转移失败
sentinel failover-timeout master-6379 180000

3) 启动哨兵模式

通过src目录下的 redis-sentinel 命令 和对应的配置文件启动,如果配置文件有错误,则会启动失败,并且提示哪一行的配置错误,可以根据提示进行修改,然后在启动

4)查看 sentinel 启动结果

3.4 验证哨兵机制

1) 方法: 我们将 Master 关机模拟宕机情况,查看剩余的Slave 是否会选择出一个新的Master,这个主要当我们关机以后,需要稍等一会,因为哨兵巡察并且切换主机是需要一点时间的

2) 日志查看

9691:X 21 Feb 2021 23:40:23.238 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo  --Redis启动
9691:X 21 Feb 2021 23:40:23.238 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=9691, just started  --Redis状态
9691:X 21 Feb 2021 23:40:23.238 # Configuration loaded -- 配置加载成功
9692:X 21 Feb 2021 23:40:23.239 * Increased maximum number of open files to 10032 (it was originally set to 1024).
9692:X 21 Feb 2021 23:40:23.240 * Running mode=sentinel, port=26379. --哨兵运行端口号
9692:X 21 Feb 2021 23:40:23.240 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
9692:X 21 Feb 2021 23:40:23.324 # Sentinel ID is d4c24c45edb70ef0bd422c9f3139233e5eb9d90d --哨兵ID
9692:X 21 Feb 2021 23:40:23.324 # +monitor master master-6379 127.0.0.1 6379 quorum 1 --添加哨兵监控的主节点
9692:X 21 Feb 2021 23:40:23.326 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master-6379 127.0.0.1 6379  --添加监控的从节点
9692:X 21 Feb 2021 23:40:23.329 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master-6379 127.0.0.1 6379  --添加监控的从节点
9692:X 21 Feb 2021 23:41:46.972 # +sdown master master-6379 127.0.0.1 6379 --主节点进行SDOWN状态
9692:X 21 Feb 2021 23:41:46.972 # +odown master master-6379 127.0.0.1 6379 #quorum 1/1  --投票成功,主节点确认宕机,进入ODOWN状态
9692:X 21 Feb 2021 23:41:46.972 # +new-epoch 1  --当前配置版本被更新时
9692:X 21 Feb 2021 23:41:46.972 # +try-failover master master-6379 127.0.0.1 6379  --达到failover条件,正等待其他sentinel的选举
9692:X 21 Feb 2021 23:41:46.974 # +vote-for-leader d4c24c45edb70ef0bd422c9f3139233e5eb9d90d 1  --投票这个节点宕机
9692:X 21 Feb 2021 23:41:46.974 # +elected-leader master master-6379 127.0.0.1 6379  --被选举为去执行failover的时候
9692:X 21 Feb 2021 23:41:46.974 # +failover-state-select-slave master master-6379 127.0.0.1 6379  --开始要选择一个slave当选新master时
9692:X 21 Feb 2021 23:41:47.036 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master-6379 127.0.0.1 6379  --找到了一个适合的slave来担当新master
9692:X 21 Feb 2021 23:41:47.037 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ master-6379 127.0.0.1 6379 --将6381执行SLAVEOF NO ONE 命令
9692:X 21 Feb 2021 23:41:47.089 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ master-6379 127.0.0.1 6379 --等待6381从机切换
9692:X 21 Feb 2021 23:41:47.581 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master-6379 127.0.0.1 6379 --宣布从机升级为主机
9692:X 21 Feb 2021 23:41:47.581 # +failover-state-reconf-slaves master master-6379 127.0.0.1 6379  --Failover状态变为reconf-slaves状态时
9692:X 21 Feb 2021 23:41:47.640 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ master-6379 127.0.0.1 6379 --sentinel发送SLAVEOF命令把它重新配置时
9692:X 21 Feb 2021 23:41:48.653 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ master-6379 127.0.0.1 6379  slave被重新配置为另外一个master的slave,但数据复制还未发生时
9692:X 21 Feb 2021 23:41:48.653 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ master-6379 127.0.0.1 6379 --slave被重新配置为另外一个master的slave并且数据复制已经与master同步时。
9692:X 21 Feb 2021 23:41:48.730 # +failover-end master master-6379 127.0.0.1 6379 --failover成功完成时
9692:X 21 Feb 2021 23:41:48.730 # +switch-master master-6379 127.0.0.1 6379 127.0.0.1 6381 --当master的地址发生变化时
9692:X 21 Feb 2021 23:41:48.731 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master-6379 127.0.0.1 6381
9692:X 21 Feb 2021 23:41:48.731 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ master-6379 127.0.0.1 6381
9692:X 21 Feb 2021 23:42:18.752 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ master-6379 127.0.0.1 6381

3)重启服务器 

当我们将服务器重启以后,这里需要稍等几秒钟,然后查看状态,发现其会自动以从机的身份加入到主从复制模式中

3.5 发布与订阅消息

sentinel的日志文件里可以看到这些信息

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

以下列出的是客户端可以通过订阅来获得的频道和信息的格式: 第一个英文单词是频道/事件的名字, 其余的是数据的格式。

如果这个redis实例是一个master,那么@之后的消息就不会显示。

    +reset-master <instance details> -- 当master被重置时.
    +slave <instance details> -- 当检测到一个slave并添加进slave列表时.
    +failover-state-reconf-slaves <instance details> -- Failover状态变为reconf-slaves状态时
    +failover-detected <instance details> -- 当failover发生时
    +slave-reconf-sent <instance details> -- sentinel发送SLAVEOF命令把它重新配置时
    +slave-reconf-inprog <instance details> -- slave被重新配置为另外一个master的slave,但数据复制还未发生时。
    +slave-reconf-done <instance details> -- slave被重新配置为另外一个master的slave并且数据复制已经与master同步时。
    -dup-sentinel <instance details> -- 删除指定master上的冗余sentinel时 (当一个sentinel重新启动时,可能会发生这个事件).
    +sentinel <instance details> -- 当master增加了一个sentinel时。
    +sdown <instance details> -- 进入SDOWN状态时;
    -sdown <instance details> -- 离开SDOWN状态时。
    +odown <instance details> -- 进入ODOWN状态时。
    -odown <instance details> -- 离开ODOWN状态时。
    +new-epoch <instance details> -- 当前配置版本被更新时。
    +try-failover <instance details> -- 达到failover条件,正等待其他sentinel的选举。
    +elected-leader <instance details> -- 被选举为去执行failover的时候。
    +failover-state-select-slave <instance details> -- 开始要选择一个slave当选新master时。
    no-good-slave <instance details> -- 没有合适的slave来担当新master
    selected-slave <instance details> -- 找到了一个适合的slave来担当新master
    failover-state-send-slaveof-noone <instance details> -- 当把选择为新master的slave的身份进行切换的时候。
    failover-end-for-timeout <instance details> -- failover由于超时而失败时。
    failover-end <instance details> -- failover成功完成时。
    switch-master <master name> <oldip> <oldport> <newip> <newport> -- 当master的地址发生变化时。通常这是客户端最感兴趣的消息了。
    +tilt -- 进入Tilt模式。
    -tilt -- 退出Tilt模式。

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44051038/article/details/113916776

redis sentinel(哨兵) 和 master+slave(主从)的实现和原理分析_奔跑的大大蜗牛的博客-爱代码爱编程

最近需要将项目的的Redis的缓存介入CacheCloundpingt来管理Redis的,所以找了下相关资料来更好的巩固下Redis的相关知识; 原文地址(https://blog.csdn.net/qq_26334813/article/details/78298025?locationNum=8&fps=1) 单节点 server01  se

采用 redis主从 + 哨兵(sentinel) + vip漂移搭建一套redis高可用集群_诸葛本不亮的博客-爱代码爱编程

一、单个实例 当系统中只有一台redis运行时,一旦该redis挂了,会导致整个系统无法运行。 单个实例 二、备份 由于单台redis出现单点故障,就会导致整个系统不可用,所以想到的办法自然就是备份(一般工业界认为比较安全的备份数应该是3份)。当一台redis出现问题了,另一台redis可以继续提供服务。 备份 三、自动故障转移 虽然

redis进击(三)搭建redis高可用集群的哨兵模式(redis-sentinel)【windows环境】-爱代码爱编程

楔子:某个时间,由于不清不楚的某些原因,导致了一次严重的线上事故。后来,开发不清不楚的配合把项目升级到了 Redis 高可用集群的哨兵模式(Redis-Sentinel),再后来,我们逐渐的又不清不楚的淡忘了这件事。节点化的工作很容易导致一定程度上只知其然而不知其所以然,这是项目开发中的一个众相。回想起来,我还是想记点什么。 该篇可以为 Red

redis的哨兵模式sentinel配置与启动-爱代码爱编程

如果redis主从复制的master服务器挂掉了,那么整体redis就崩溃了,因为master无法进行写数据,导致slave中无法更新数据。 那么为了解决这个问题我们就需要有一种方案让redis宕机后可以自动进行故障转移,还好redis给我们提供一种高可用解决方案 Redis-Sentinel。Redis-sentinel本身也是一个独立运行的进

Redis高可用故障转移 Redis Sentinel 哨兵模式 从配置到编码一气呵成-爱代码爱编程

点赞多大胆,就有多大产!路漫漫其修远兮,吾将上下而求索,献给每一位技术使用者和爱好者! 干货满满,摆好姿势,点赞发车 Redis Sentinel介绍 主从复制出现的问题 上篇文章《Redis主从复制》中我们说到可以对Redis单节点数据进行备份实现Redis高可用,但是如果master节点宕机并不会自动做故障切换等,导致项目中更可能需

Redis分布式集群实战(三)——搭建Redis哨兵(Sentinel)模式[高可用]-爱代码爱编程

文章目录 一、哨兵模式1、定义2、功能作用3、原理4、工作方式5、配置文件二、搭建Redis哨兵模式解读6379.conf 文件中部分参数信息三、故障转移的具体步骤: 一、哨兵模式 主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。 哨兵模式就是为了解决此类

redis 高可用主从+哨兵模式配置以及整合springboot使用-爱代码爱编程

首先准备三台redis服务。高可用基本上都是选用大于3台服务 先设置主从关系: 先选用一个节点为主节点。我这里用6380作为主。在其他两个服务redis.conf中增加slaveof 127.0.0.1:6380 因为是要做哨兵模式。所以每个节点都要设置可以写。在三个服务中redis.conf更改 slave-read-only为no。 并

Redis 哨兵模式下,Master节点宕机后,进行故障转移的过程-爱代码爱编程

有三台服务器 S1:192.168.50.121 S2:192.168.50.122 S3:192.168.50.123 其中S1、S2上部署了Redis服务和Redis sentinel,S3上只部署了Redis sentinel。 假设S1是Master,突然宕机,在经过一段时间后(down_after_milliseconds),可以看到控

Redis高可用方案:sentinel(哨兵模式)以及springboot整合sentinel模式-爱代码爱编程

一、前言 单点的redis如果崩溃或者宕机了,是很容易造成程序问题的。所以需要高可用的redis方案。sentinel是常用的redis高可用方案之一,本篇文章将记录整个搭建过程。 二、图解 我采用的是一主二从三哨兵,如图:  三、关于 Redis Sentinel 的概念 Redis Sentinel(译为“哨兵”)是 Redis 官方推荐

吃透Redis系列(七):哨兵机制详细介绍-爱代码爱编程

Redis系列文章: 吃透Redis系列(一):Linux下Redis安装 吃透Redis系列(二):Redis六大数据类型详细用法 吃透Redis系列(三):Redis管道,发布/订阅,事物,过期时间 详细介绍 吃透Redis系列(四):布隆(bloom)过滤器详细介绍 吃透Redis系列(五):RDB和AOF持久化详细介绍 吃透Redis系

Redis系列——第七章 Redis开启哨兵模式-爱代码爱编程

Redis系列 Redis系列——第一章 Redis配置文件 Redis系列——第二章 Redis数据类型以及基本使用 Redis系列——第三章 Redis开启事务并实现乐观锁 Redis系列——第四章 Redis发布订阅模式 Redis系列——第五章 Redis持久化策略RDB与AOF Redis系列——第六章 Redis主从同步 Redi

Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理-爱代码爱编程

概要 我们知道「主从复制是高可用的基石」,从库宕机依然可以将请求发送给主库或者其他从库,但是 Master 宕机,只能响应读操作,写请求无法再执行。 所以主从复制架构面临一个严峻问题,主库挂了,无法执行「写操作」,无法自动选择一个 Slave 切换为 Master,也就是无法故障自动切换。 深夜与女朋友么么哒……(此处省略 10000 字),突

Redis高可用方案(一):主从复制与哨兵机制-爱代码爱编程

Redis高可用方案(一):主从复制与哨兵机制 “高可用性”(High Availability) 通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。CAP的A AP模型 单机的Redis是无法保证高可用性的,当Redis服务器宕机后,即使在有持久化的机制下也无法保证不丢失数据。 所以我们采用Redis多机和集群的方式来保

Redis-主从复制高可用之哨兵(Sentinel)-爱代码爱编程

Redis-主从复制集群高可用之哨兵(Sentinel) 1. 基本知识 1)哨兵的功能 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。自动故障迁

【196期】Redis高可用方案:sentinel(哨兵模式)和集群-爱代码爱编程

点击上方“Java精选”,选择“设为星标” 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... 一. redis高可用方案–sentinel(哨兵模式) 当我们搭建好redis主从复制方案后会发现一个问题,那就是当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要

redis 中的 哨兵(sentinel) 基本概念 sentinel的高可用性_sentinel高可用-爱代码爱编程

这里写目录标题 9.1 基本概念9.1.1 主从复制的问题9.1.2 高可用9.1.3 Redis Sentinel的高可用性 参考目录 9.1 基本概念         由于对Red