文章目录
Redis学习笔记-哨兵机制&哨兵集群建立过程
前面介绍了 Redis
主从模型如何在不影响正常业务的情况下实现数据一致,若从库发生故障,客户端可以请求其他的从库(或主库)读取数据,若主库发生故障,客户端就无法写入了,而且还会影响从库的数据复制,这个时候就需要考虑主从切换了,这篇文章就来学习下 Redis
哨兵机制和哨兵集群
。
1.笔记图
2.Redis 从库切换为主库需要思考的问题
- 主库真的挂了吗?
- 该选择哪个从库作为主库?
- 怎么把新主库的相关信息通知给从库和客户端呢?
3.哨兵机制
- 说明:哨兵其实就是一个运行在特殊模式下的
Redis
进程,主从库实例运行的同时,它也在运行 - 职责:监控、选主、通知
3.1 监控
-
主库:如果主库也没有在规定时间内响应哨兵的 PING 命令,哨兵就会判定主库下线,然后开始自动切换主库的流程
-
主观下线:如果哨兵发现主库对
PING
命令的响应超时了,标记为主观下线
-
客观下线:只有大多数的哨兵实例,都判断主库已经
主观下线
了,主库才会被标记为客观下线
,当有N
个哨兵实例时,最好要有N/2 + 1
个实例判断主库为主观下线
,才能最终判定主库为客观下线
-
从库:如果从库没有在规定时间内响应哨兵的
PING
命令,哨兵就会把它标记为下线状态
3.2 选主
- 说明:主库挂了以后,哨兵就需要从很多个从库里,按照一定的规则选择一个从库实例,把它作为新的主库
- 选主规则:
- 检查从库当前在线状态,还需要判断之前网络连接状态,如配置
down-after-milliseconds * 10
表示如果发生断连超过10
次,不适合选为新主库 - 第一轮:优先级最高的得分高,如配置
slave-priority
设置从库的优先级 - 第二轮:和原来的断开的主库同步数据最接近的得分高,判断
repl_backlog_buffer
中的master_repl_offset
和slave_repl_offset
位置 - 第三轮:在优先级和复制进度都相同的情况下,
ID
号最小的会被选为新主库
3.3 通知
- 哨兵会把新主库的连接信息发给其他从库,让它们执行
replicaof
命令,从新去新主库建立连接,同步数据
Tips:主从切换引发的思考:如果有哨兵实例在运行时发生了故障,主从库还能正常切换吗?
4.笔记图
5.Redis哨兵集群建立过程
5.1 功能说明
- 哨兵其实就是一个运行在特殊模式下的
Redis
实例,主从库实例运行的同时,它也在运行,多个实例可组成哨兵集群 - 即使有哨兵实例出现故障挂掉了,其他哨兵还能继续协作完成主从库切换的工作
- 它的职责是监控、选主、通知
5.2 Redis 如何配置哨兵
- 给Redis增加配置项,设置主库的
IP
和端口号 sentinel monitor <master-name> <ip> <redis-port> <quorum>
6.Redis 哨兵集群组成原理
-
哨兵之间可以相互发现,基于
pub/sub
机制 -
哨兵基于
pub/sub
机制和主库建立连接,从主库上订阅消息和发布消息(如IP
和端口) -
哨兵之间建立连接:
-
只有订阅了同一个频道的哨兵,才能
发布/订阅
信息交换,并且不影响客户端此功能 -
__sentinel__:hello
频道用于哨兵互相通信频道(客户端发布/订阅使用另外频道) -
哨兵和从库建立连接(连接后监控从库):
-
哨兵给主库发送
INFO
,主库就会把从库列表返回给哨兵 -
哨兵可以根据从库列表信息和每个从库连接,并对从库进行监控
-
哨兵和客户端建立连接(连接后可通知):
-
每个哨兵实例也会提供
pub/sub
机制 -
客户端可以从哨兵订阅消息
-
哨兵提供的消息订阅频道,不同频道包含了主从库切换过程中的不同关键事件
-
举例
# 订阅“所有实例进入客观下线状态的事件”
SUBSCRIBE +odown
# 订阅所有的事件
PSUBSCRIBE *
- 若客户端看到
switch-master
,表示这个事件主库已经切换了,新主库的IP
地址和端口信息已经有了,客户端就可以用这里面的新主库地址和端口进行通信了
7.Redis哨兵选Leader
-
判断客观下线:
-
任何一个哨兵实例只要判断主库
主观下线
,就会给其他哨兵实例发送is-master-down-by-addr
命令 -
收到
is-master-down-by-addr
命令的实例会根据自己和主库的连接情况,做出Y
或N
的响应(Y
赞成,N
反对) -
哨兵获得了仲裁所需的赞成票数后,就可以标记主库为
客观下线
,这个所需赞成票通过quorum
配置项决定,如quorum
配置为3
,则该哨兵判断主库客观下线
需要3
票赞成(包括了自己的1
票) -
Leader 选举
-
哨兵拿到赞成
主库下线
的票数大于等于quorum
,就确定了主库客观下线
-
哨兵就可以再给其他哨兵发送命令,表明希望由自己担任执行主从切换的
Leader
-
在投票过程中,任何一个想成为
Leader
的哨兵,要满足两个条件:拿到半数以上的赞成票和拿到的票数同时还需要大于等于哨兵配置文件中的quorum
值 -
Leader选举举例:
-
T1时刻:
A
判断主库为客观下线
,它想成为Leader
,就先给自己投1
张赞成票,然后分别向B
和C
发送命令,表示要成为Leader
-
T2时刻:
C
判断主库为客观下线
,它也想成为Leader
,所以也先给自己投1
张赞成票,再分别向A
和B
发送命令,表示要成为Leader
-
T3 时刻:
A
收到了C
的 Leader 投票请求。因为A
已经给自己投了1
票Y
,所以它不能再给其他哨兵投赞成票了,所以A
回复N
表示不同意。同时,B
收到了T2
时C
发送的Leader
投票请求。因为B
之前没有投过票,它会给第一个向它发送投票请求的哨兵回复Y
,给后续再发送投票请求的哨兵回复N
,所以,在T3
时,B
回复C
,同意C
成为Leader
-
T4 时刻:
B
才收到T1
时A
发送的投票命令。因为B
已经在T3
时同意了C
的投票请求,此时,B
给A
回复N
,表示不同意A
成为Leader
。发生这种情况,是因为C
和B
之间的网络传输正常,而A
和B
之间的网络传输可能正好拥塞了,导致投票请求传输慢了 -
T5 时刻:
A
得到的票数是来自它自己的1
票Y
和来自B
的1
票N
。而C
除了自己的赞成票Y
以外,还收到了来自B
的一票Y
。此时,C
不仅获得了半数以上的Leader
赞成票,也达到预设的quorum
值(quorum
为2
),所以它最终成为了Leader
。接着,C
会开始执行选主操作,而且在选定新主库后,会给其他从库和客户端通知新主库的信息
Tips:注意坑:要保证所有哨兵实例的配置是一致的,尤其是主观下线的判断值
down-after-milliseconds
,否则导致哨兵集群一直没有对有故障的主库形成共识,也就没有及时切换主库,最终的结果就是集群服务不稳定。
扫码关注