简易架构图
哨兵
在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从节点(slave)进行数据同步了。
这时如果要恢复服务的话,需要人工介入,选择一个「从节点」切换为「主节点」,然后让其他从节点指向新的主节点,同时还需要通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。人工操作就会太麻烦,所以这时就可以使用”哨兵“
Redis 在 2.8 版本以后提供的哨兵(*Sentinel*)机制,它的作用是实现主从节点故障转移。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。
哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master,最后把新主节点的相关信息通知给从节点和客户端
sentinel 主要配置文件在 redis 解压文件路径下 sentinel.conf ,和 redis.conf 在同一位置
修改配置文件 sentinel.conf
参数 | 作用 |
---|---|
protected-mode no | 开启外网访问保护模式,no表示关闭,这样外网可以访问 |
port 26379 | 端口配置 26379 |
daemonize no | 后台启动,与Redis一致,yes表示后台启动 |
pidfile /var/run/redis-sentinel.pid | pid 文件路径 |
logfile “/opt/tools/redis/log/redis.log” | 自定义 logfile 路径,注意修改文件权限 |
dir /tmp | Sentinel工作目录 |
sentinel monitor mymaster 192.168.169.150 6379 2 | mymaste 自定义主机名 192.168.169.150 master 主机ip 6379 redis 端口 2[quorum] 指明当有多少个sentinel认为一个master失效时,master才算真正失效 |
sentinel down-after-milliseconds mymaster 30000 | 这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒 |
sentinel parallel-syncs mymaster 1 | 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。 |
sentinel failover-timeout mymaster 180000 | failover-timeout 可以用在以下这些方面: 1. 同一个sentinel对同一个master两次failover(主观下线)之间的间隔时间。 2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。 3.当想要取消一个正在进行的failover所需要的时间。 4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。 |
# 后台运行
daemonize yes
# 日志文件
logfile "/opt/tools/redis/log/sentinel.log"
# master 地址绑定(后面故障转移时会自动配置新的 master 地址)
sentinel monitor mymaster 192.168.169.150 6379 2
# 注:如果 master 配置了密码,这里不配置,那么日志信息里就看不到 master 的状态
sentinel auth-pass mymaster 123456
# sentinel 地址(有待测试,不配置是否也没问题)
sentinel announce-ip 192.168.169.151
其他参数使用默认值
注意:master 和 slave 都需要配置相应的密码保护 requirepass 和访问时的连接密码 masterauth
# 外部访问(应该可以不用配置,后期在测试)
bind 0.0.0.0 -::1
# 后台启动
daemonize yes
# 配置日志路径,后台启动时便于查看日志
logfile "/opt/tools/redis/log/redis.log"
# 当 master 服务设置了密码保护时,slave 服务连接 master 的密码(master也要配置,因为它宕机之后也连接新的 master 也需要认证)
masterauth "123456"
# 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH 命令提供密码,默认关闭
requirepass "123456"
[root@master ~]# redis-server /opt/tools/redis/redis-stable/redis.conf
[root@master ~]# redis-sentinel /opt/tools/redis/redis-stable/sentinel.conf
这里可以看到宕机之前两台从机的信息
主机宕机之前和宕机之后哨兵监控信息的变化
哨兵选择 leader 及主从切换过程,原理图参考下面 8.4 8.5 章节
详情参考下面日志信息详情
1893:X 21 Jun 2022 00:10:24.765 # +sdown master mymaster 192.168.169.150 6379
1893:X 21 Jun 2022 00:10:24.881 * Sentinel new configuration saved on disk
1893:X 21 Jun 2022 00:10:24.881 # +new-epoch 1
1893:X 21 Jun 2022 00:10:24.895 * Sentinel new configuration saved on disk
1893:X 21 Jun 2022 00:10:24.897 # +vote-for-leader 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1893:X 21 Jun 2022 00:10:25.581 # +config-update-from sentinel 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 192.168.169.151 26379 @ mymaster 192.168.169.150 6379
1893:X 21 Jun 2022 00:10:25.581 # +switch-master mymaster 192.168.169.150 6379 192.168.169.152 6379
1893:X 21 Jun 2022 00:10:25.584 * +slave slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.152 6379
1893:X 21 Jun 2022 00:10:25.584 * +slave slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
1893:X 21 Jun 2022 00:10:25.593 * Sentinel new configuration saved on disk
1893:X 21 Jun 2022 00:10:55.666 # +sdown slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
# sdown 主观下线
1833:X 21 Jun 2022 00:10:24.815 # +sdown master mymaster 192.168.169.150 6379
# 此时已经有两个哨兵判断主观下线,因此满足条件后变成客观下线
1833:X 21 Jun 2022 00:10:24.872 # +odown master mymaster 192.168.169.150 6379 #quorum 3/2
# 递增集群状态版本号,这个版本号将被接下来选举出的新的master采用。从这个可以看出,集群版本号是哨兵创建和维护的。
1833:X 21 Jun 2022 00:10:24.872 # +new-epoch 1
# 开始对IP为192.168.169.150,端口为6379,名为"mymaster"的Redis集群进行故障转移。
1833:X 21 Jun 2022 00:10:24.872 # +try-failover master mymaster 192.168.169.150 6379
# 在磁盘上保存 sentinel 新的配置信息
1833:X 21 Jun 2022 00:10:24.875 * Sentinel new configuration saved on disk
# 在哨兵集群中投票选举出一个哨兵,作为本次执行故障转移操作的leader。
1833:X 21 Jun 2022 00:10:24.875 # +vote-for-leader 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
# 一个哨兵投票给另一个哨兵
1833:X 21 Jun 2022 00:10:24.890 # 578f67b7a622cab16db900148ac06b935c9d4543 voted for 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1833:X 21 Jun 2022 00:10:24.903 # 316b0e0570f849c58f8ac87af0b798aca3bd172d voted for 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1833:X 21 Jun 2022 00:10:24.931 # +elected-leader master mymaster 192.168.169.150 6379
1833:X 21 Jun 2022 00:10:24.931 # +failover-state-select-slave master mymaster 192.168.169.150 6379
# 出现"+selected-slave"意味着已经找到了合适的slave作为新的master
1833:X 21 Jun 2022 00:10:25.032 # +selected-slave slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
# Leader向目标slave发送"slaveof-noone"指令,令其不要再做其它任何节点的slave了,从现在开始,它就是老大,完成从slave到master的转换。
1833:X 21 Jun 2022 00:10:25.032 * +failover-state-send-slaveof-noone slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
# 等待其它的sentinel确认slave
1833:X 21 Jun 2022 00:10:25.086 * +failover-state-wait-promotion slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
1833:X 21 Jun 2022 00:10:25.523 * Sentinel new configuration saved on disk
# ”+promoted-slave“ 意味着其它的sentinel全部确认成功。
1833:X 21 Jun 2022 00:10:25.524 # +promoted-slave slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
# 开始对集群中的所有slave做reconf操作(更新配置信息)
1833:X 21 Jun 2022 00:10:25.524 # +failover-state-reconf-slaves master mymaster 192.168.169.150 6379
# 向指定的slave发送"slaveof"指令,令其跟随新的master。
1833:X 21 Jun 2022 00:10:25.567 * +slave-reconf-sent slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.150 6379
# 客观下线
1833:X 21 Jun 2022 00:10:25.972 # -odown master mymaster 192.168.169.150 6379
# 目标slave正在执行slaveof操作,如果在此期间,又接收到了新的"slave-reconf-sent"命令,则在会在当前操作执行完毕后,再次执行slaveof。
1833:X 21 Jun 2022 00:10:26.585 * +slave-reconf-inprog slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.150 6379
# 目标slave配置信息更新完毕,leader可以对下一个slave开始reconfig操作了。
1833:X 21 Jun 2022 00:10:26.585 * +slave-reconf-done slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.150 6379
# 本次故障转移完毕
1833:X 21 Jun 2022 00:10:26.639 # +failover-end master mymaster 192.168.169.150 6379
# 故障转移完毕后,各个sentinel开始监控新的master。这句话执行完毕后,我们可以去哨兵的配置文件中看到,sentinel monitor mymaster后面的ip已经发生了变化。
1833:X 21 Jun 2022 00:10:26.639 # +switch-master mymaster 192.168.169.150 6379 192.168.169.152 6379
# 主从信息的改变
1833:X 21 Jun 2022 00:10:26.640 * +slave slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.152 6379
1833:X 21 Jun 2022 00:10:26.640 * +slave slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
# 新的信息保存在磁盘上
1833:X 21 Jun 2022 00:10:26.653 * Sentinel new configuration saved on disk
# 此时 slave 192.168.169.150:6379 是不在线的
1833:X 21 Jun 2022 00:10:56.689 # +sdown slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:24.809 # +sdown master mymaster 192.168.169.150 6379
1813:X 21 Jun 2022 00:10:24.877 * Sentinel new configuration saved on disk
1813:X 21 Jun 2022 00:10:24.877 # +new-epoch 1
1813:X 21 Jun 2022 00:10:24.884 * Sentinel new configuration saved on disk
1813:X 21 Jun 2022 00:10:24.884 # +vote-for-leader 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1813:X 21 Jun 2022 00:10:24.897 # +odown master mymaster 192.168.169.150 6379 #quorum 3/2
1813:X 21 Jun 2022 00:10:24.897 # Next failover delay: I will not start a failover before Tue Jun 21 00:16:25 2022
1813:X 21 Jun 2022 00:10:25.565 # +config-update-from sentinel 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 192.168.169.151 26379 @ mymaster 192.168.169.150 6379
1813:X 21 Jun 2022 00:10:25.565 # +switch-master mymaster 192.168.169.150 6379 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:25.566 * +slave slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:25.566 * +slave slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:25.580 * Sentinel new configuration saved on disk
1813:X 21 Jun 2022 00:10:55.575 # +sdown slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
启动之后,原来的 master 就会变成现在 master 的 salve
每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方宕机了,这就是所谓的”主观认为宕机”Subjective Down,简称sdown)。
若“哨兵群”中的多数sentinel(即哨兵的赞同票数达到哨兵配置文件中的 quorum
配置项设定的值后),都报告某一master没响应,系统才认为该master真正宕机,即客观上认为宕机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。客观下线只适用于主节点。
解析:
假设哨兵1先检测到主服务器宕机,系统不会马上进行failover (故障转移) 过程,仅仅是哨兵1主观认为主服务器不可用——主观下线 当哨兵2、3也检测到服务器不可用,并且数量达到一定值时,哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为“客观下线”
之所以针对「主节点」设计「主观下线」和「客观下线」两个状态,是因为有可能「主节点」其实并没有故障,可能只是因为主节点的系统压力比较大或者网络发送了拥塞,导致主节点没有在规定时间内响应哨兵的 PING 命令。
所以,为了减少误判的情况,哨兵在部署的时候不会只部署一个节点,而是用多个节点部署成哨兵集群(最少需要三台机器来部署哨兵集群),通过多个哨兵节点一起判断,就可以就可以避免单个哨兵因为自身网络状况不好,而误判主节点下线的情况。同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。
如果在 cluster-node-timeout 15000(默认是 15000) 时间内无法收集到一半以上节点的下线报告, 那么之前的下线报告将会过期, 也就是说主观下线上报的速度追赶不上下线报告过期的速度, 那么故障节点将永远无法被标记为客观下线从而导致故障转移失败。 因此不建议将 cluster-node-timeout 设置得过小。
参考文档:Redis中哨兵选举算法
为了更加“客观”的判断主节点故障了,一般不会只由单个哨兵的检测结果来判断,而是多个哨兵一起判断,这样可以减少误判概率,所以哨兵是以哨兵集群的方式存在的。
❓ 由哨兵集群中的哪个节点进行主从故障转移呢?
这时候,还需要在哨兵集群中选出一个 leeder,让 leeder 来执行主从切换。
选举 leeder 的过程其实是一个投票的过程,在投票开始前,肯定得有个「候选者」。
候选者即为每个判断主服务器主观下线的 sentinel
a:哨兵实例只有在自己判定主库下线时,才会给自己投票,而其他的哨兵实例会把票投给第一个来要票的请求,其后的都拒绝
b:如果出现多个哨兵同时发现主库下线并给自己投票,导致投票选举失败,就会触发新一轮投票,直至成功。这种情况相对较少,受网络波动,及服务器使用情况限制等情况,多个哨兵同时判定主观下线的概率较小。
在哨兵集群中通过投票的方式,选举出了哨兵 leader 后,就可以进行主从故障转移的过程了,如下图:
主从故障转移操作包含以下四个步骤:
故障转移操作第一步要做的就是在已下线主节点属下的所有「从节点」中,挑选出一个状态良好、数据完整的从节点,然后向这个「从节点」发送 SLAVEOF no one 命令,将这个「从节点」转换为「主节点」。
主要围绕着4点
1️⃣ 如何判断从节点之前的网络连接状况?
Redis 有个叫 down-after-milliseconds * 10 配置项,其down-after-milliseconds 是主从节点断连的最大连接超时时间。如果在 down-after-milliseconds 毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了。如果发生断连的次数超过了 10 次,就说明这个从节点的网络状况不好,不适合作为新主节点。
# sentinel down-after-milliseconds
#
# Number of milliseconds the master (or any attached replica or sentinel) should
# be unreachable (as in, not acceptable reply to PING, continuously, for the
# specified period) in order to consider it in S_DOWN state (Subjectively
# Down).
#
# Default is 30 seconds.
sentinel down-after-milliseconds mymaster 30000
2️⃣ 优先级
我们可以人为的将从节点的优先级调整,因为有些机器性能相对较好,我们就可以默认他的优先级较高
优先级越小排名越靠前
# The replica priority is an integer number published by Redis in the INFO
# output. It is used by Redis Sentinel in order to select a replica to promote
# into a master if the master is no longer working correctly.
#
# A replica with a low priority number is considered better for promotion, so
# for instance if there are three replicas with priority 10, 100, 25 Sentinel
# will pick the one with priority 10, that is the lowest.
#
# However a special priority of 0 marks the replica as not able to perform the
# role of master, so a replica with priority of 0 will never be selected by
# Redis Sentinel for promotion.
#
# By default the priority is 100.
replica-priority 100
3️⃣ 复制偏移量
如果上面优先级相同的有多个的情况下,就会继续你叫从节点的复制进度。
❓ 什么是复制进度?
主从架构中,主节点会将写操作同步给从节点,在这个过程中,主节点会用 master_repl_offset 记录当前的最新写操作在 repl_backlog_buffer 中的位置(如下图中的「主服务器已经写入的数据」的位置),而从节点会用 slave_repl_offset 这个值记录当前的复制进度(如下图中的「从服务器要读的位置」的位置)。
如果某个从节点的 slave_repl_offset 最接近 master_repl_offset,说明它的复制进度是最靠前的,于是就可以将它选为新主节点。
所以从服务器接收到的数据越多,变成主服务器的几率越大。
4️⃣ 节点 ID
重新选举 master 时,如果其他选项相同,则选择节点 ID 较小的从节点为新的 master
本章节 8.3 8.4 8.5 较为详细的展示这个案例
1893:X 21 Jun 2022 00:10:24.765 # +sdown master mymaster 192.168.169.150 6379
1893:X 21 Jun 2022 00:10:24.881 * Sentinel new configuration saved on disk
1893:X 21 Jun 2022 00:10:24.881 # +new-epoch 1
1893:X 21 Jun 2022 00:10:24.895 * Sentinel new configuration saved on disk
1893:X 21 Jun 2022 00:10:24.897 # +vote-for-leader 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1893:X 21 Jun 2022 00:10:25.581 # +config-update-from sentinel 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 192.168.169.151 26379 @ mymaster 192.168.169.150 6379
1893:X 21 Jun 2022 00:10:25.581 # +switch-master mymaster 192.168.169.150 6379 192.168.169.152 6379
1893:X 21 Jun 2022 00:10:25.584 * +slave slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.152 6379
1893:X 21 Jun 2022 00:10:25.584 * +slave slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
1893:X 21 Jun 2022 00:10:25.593 * Sentinel new configuration saved on disk
1893:X 21 Jun 2022 00:10:55.666 # +sdown slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
# sdown 主观下线
1833:X 21 Jun 2022 00:10:24.815 # +sdown master mymaster 192.168.169.150 6379
# 此时已经有两个哨兵判断主观下线,因此满足条件后变成客观下线
1833:X 21 Jun 2022 00:10:24.872 # +odown master mymaster 192.168.169.150 6379 #quorum 3/2
# 递增集群状态版本号,这个版本号将被接下来选举出的新的master采用。从这个可以看出,集群版本号是哨兵创建和维护的。
1833:X 21 Jun 2022 00:10:24.872 # +new-epoch 1
# 开始对IP为192.168.169.150,端口为6379,名为"mymaster"的Redis集群进行故障转移。
1833:X 21 Jun 2022 00:10:24.872 # +try-failover master mymaster 192.168.169.150 6379
# 在磁盘上保存 sentinel 新的配置信息
1833:X 21 Jun 2022 00:10:24.875 * Sentinel new configuration saved on disk
# 在哨兵集群中投票选举出一个哨兵,作为本次执行故障转移操作的leader。
1833:X 21 Jun 2022 00:10:24.875 # +vote-for-leader 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
# 一个哨兵投票给另一个哨兵
1833:X 21 Jun 2022 00:10:24.890 # 578f67b7a622cab16db900148ac06b935c9d4543 voted for 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1833:X 21 Jun 2022 00:10:24.903 # 316b0e0570f849c58f8ac87af0b798aca3bd172d voted for 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1833:X 21 Jun 2022 00:10:24.931 # +elected-leader master mymaster 192.168.169.150 6379
1833:X 21 Jun 2022 00:10:24.931 # +failover-state-select-slave master mymaster 192.168.169.150 6379
# 出现"+selected-slave"意味着已经找到了合适的slave作为新的master
1833:X 21 Jun 2022 00:10:25.032 # +selected-slave slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
# Leader向目标slave发送"slaveof-noone"指令,令其不要再做其它任何节点的slave了,从现在开始,它就是老大,完成从slave到master的转换。
1833:X 21 Jun 2022 00:10:25.032 * +failover-state-send-slaveof-noone slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
# 等待其它的sentinel确认slave
1833:X 21 Jun 2022 00:10:25.086 * +failover-state-wait-promotion slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
1833:X 21 Jun 2022 00:10:25.523 * Sentinel new configuration saved on disk
# ”+promoted-slave“ 意味着其它的sentinel全部确认成功。
1833:X 21 Jun 2022 00:10:25.524 # +promoted-slave slave 192.168.169.152:6379 192.168.169.152 6379 @ mymaster 192.168.169.150 6379
# 开始对集群中的所有slave做reconf操作(更新配置信息)
1833:X 21 Jun 2022 00:10:25.524 # +failover-state-reconf-slaves master mymaster 192.168.169.150 6379
# 向指定的slave发送"slaveof"指令,令其跟随新的master。
1833:X 21 Jun 2022 00:10:25.567 * +slave-reconf-sent slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.150 6379
# 客观下线
1833:X 21 Jun 2022 00:10:25.972 # -odown master mymaster 192.168.169.150 6379
# 目标slave正在执行slaveof操作,如果在此期间,又接收到了新的"slave-reconf-sent"命令,则在会在当前操作执行完毕后,再次执行slaveof。
1833:X 21 Jun 2022 00:10:26.585 * +slave-reconf-inprog slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.150 6379
# 目标slave配置信息更新完毕,leader可以对下一个slave开始reconfig操作了。
1833:X 21 Jun 2022 00:10:26.585 * +slave-reconf-done slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.150 6379
# 本次故障转移完毕
1833:X 21 Jun 2022 00:10:26.639 # +failover-end master mymaster 192.168.169.150 6379
# 故障转移完毕后,各个sentinel开始监控新的master。这句话执行完毕后,我们可以去哨兵的配置文件中看到,sentinel monitor mymaster后面的ip已经发生了变化。
1833:X 21 Jun 2022 00:10:26.639 # +switch-master mymaster 192.168.169.150 6379 192.168.169.152 6379
# 主从信息的改变
1833:X 21 Jun 2022 00:10:26.640 * +slave slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.152 6379
1833:X 21 Jun 2022 00:10:26.640 * +slave slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
# 新的信息保存在磁盘上
1833:X 21 Jun 2022 00:10:26.653 * Sentinel new configuration saved on disk
# 此时 slave 192.168.169.150:6379 是不在线的
1833:X 21 Jun 2022 00:10:56.689 # +sdown slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:24.809 # +sdown master mymaster 192.168.169.150 6379
1813:X 21 Jun 2022 00:10:24.877 * Sentinel new configuration saved on disk
1813:X 21 Jun 2022 00:10:24.877 # +new-epoch 1
1813:X 21 Jun 2022 00:10:24.884 * Sentinel new configuration saved on disk
1813:X 21 Jun 2022 00:10:24.884 # +vote-for-leader 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 1
1813:X 21 Jun 2022 00:10:24.897 # +odown master mymaster 192.168.169.150 6379 #quorum 3/2
1813:X 21 Jun 2022 00:10:24.897 # Next failover delay: I will not start a failover before Tue Jun 21 00:16:25 2022
1813:X 21 Jun 2022 00:10:25.565 # +config-update-from sentinel 82dc6d3fbb6b5fec77fcc7942e1af124b6f69d92 192.168.169.151 26379 @ mymaster 192.168.169.150 6379
1813:X 21 Jun 2022 00:10:25.565 # +switch-master mymaster 192.168.169.150 6379 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:25.566 * +slave slave 192.168.169.151:6379 192.168.169.151 6379 @ mymaster 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:25.566 * +slave slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
1813:X 21 Jun 2022 00:10:25.580 * Sentinel new configuration saved on disk
1813:X 21 Jun 2022 00:10:55.575 # +sdown slave 192.168.169.150:6379 192.168.169.150 6379 @ mymaster 192.168.169.152 6379
启动之后,原来的 master 就会变成现在 master 的 salve
在选举出从节点后,哨兵 leader 向被选中的从节点发送 SLAVEOF no one
命令,让这个从节点解除从节点的身份,将其变为新主节点。
如下图,哨兵 leader 向被选中的从节点 server2 发送 SLAVEOF no one
命令,将该从节点升级为新主节点。
在发送 SLAVEOF no one 命令之后,哨兵 leader 会以每秒一次的频率向被升级的从节点发送 INFO 命令(没进行故障转移之前,INFO 命令的频率是每十秒一次),并观察命令回复中的角色信息,当被升级节点的角色信息从原来的 slave 变为 master 时,哨兵 leader 就知道被选中的从节点已经顺利升级为主节点了。
当新主节点出现之后,哨兵 leader 下一步要做的就是,让已下线主节点属下的所有「从节点」指向「新主节点」,这一动作可以通过向「从节点」发送 SLAVEOF 命令来实现。
如下图,哨兵 leader 向所有从节点(server3和server4)发送 SLAVEOF ,让它们成为新主节点的从节点
所有从节点指向新主节点
当旧主节点重新上线时,哨兵集群就会向它发送 SLAVEOF
命令,让它成为新主节点的从节点
经过前面一系列的操作后,哨兵集群终于完成主从切换的工作,那么新主节点的信息要如何通知给客户端呢?
这主要通过 Redis 的发布者/订阅者机制来实现的。每个哨兵节点提供发布者/订阅者机制,客户端可以从哨兵订阅消息。
哨兵提供的消息订阅频道有很多,不同频道包含了主从节点切换过程中的不同关键事件,几个常见的事件如下:
客户端和哨兵建立连接后,客户端会订阅哨兵提供的频道。主从切换完成后,哨兵就会向 +switch-master 频道发布新主节点的 IP 地址和端口的消息,这个时候客户端就可以收到这条信息,然后用这里面的新主节点的 IP 地址和端口进行通信了。
通过发布者/订阅者机制机制,有了这些事件通知,客户端不仅可以在主从切换后得到新主节点的连接信息,还可以监控到主从节点切换过程中发生的各个重要事件。这样,客户端就可以知道主从切换进行到哪一步了,有助于了解切换进度。
哨兵节点之间是通过 Redis 的发布者/订阅者机制来相互发现的。
在主从集群中,主节点上有一个名为__sentinel__:hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的。
在下图中,哨兵 A 把自己的 IP 地址和端口的信息发布到__sentinel__:hello 频道上,哨兵 B 和 C 订阅了该频道。那么此时,哨兵 B 和 C 就可以从这个频道直接获取哨兵 A 的 IP 地址和端口号。然后,哨兵 B、C 可以和哨兵 A 建立网络连接。
通过这个方式,哨兵 B 和 C 也可以建立网络连接,这样一来,哨兵集群就形成了。
主节点知道所有「从节点」的信息,所以哨兵会每 10 秒一次的频率向主节点发送 INFO 命令来获取所有「从节点」的信息。
如下图所示,哨兵 B 给主节点发送 INFO 命令,主节点接受到这个命令后,就会把从节点列表返回给哨兵。接着,哨兵就可以根据从节点列表中的连接信息,和每个从节点建立连接,并在这个连接上持续地对从节点进行监控。哨兵 A 和 C 可以通过相同的方法和从节点建立连接。
通过 Redis 的发布者/订阅者机制,哨兵之间可以相互感知,然后组成集群,同时,哨兵又通过 INFO 命令,在主节点里获得了所有从节点连接信息,于是就能和从节点建立连接,并进行监控了。