概要
咱们晓得「主从复制是高可用的基石」,从库宕机仍然能够将申请发送给主库或者其余从库,然而 Master 宕机,只能响应读操作,写申请无奈再执行。
所以主从复制架构面临一个严厉问题,主库挂了,无奈执行「写操作」,无奈主动抉择一个 Slave 切换为 Master,也就是无奈 故障主动切换。
深夜与女朋友么么哒……(此处省略 10000 字),忽然宕机,总不能提起裤子从床上爬起来手工进行主从切换,再告诉其余程序员把地址从新改成新主库上线。
如此一折腾本人已被女友切换成前男友了,万万使不得。所以咱们必须有一个高可用的计划,为此,Redis 官网提供一个高可用计划——哨兵(Sentinel)。
开篇寄语
技术的迭代十分的快,然而从技术中积淀下来的思维却是受害终生的。所以不要放心什么中年危机,那些放心中年危机的人通常很难成长起来。只有咱们成长,只有咱们的认知在一直冲破,就不必放心中年危机,这个世界始终是须要那些优秀人才的。
什么是哨兵(Sentinel)
65 哥:码哥,尽管我没女朋友,然而,防患未然我要把握这个哨兵模式,避免当深夜与女朋友么么哒被打搅,你快说说哨兵的实现原理吧。
搭建实例采纳三个哨兵造成集群,三个数据节点(一主两从)形式搭建,如下图所示:
哨兵集群的搭建演示就不在这里赘述了,须要的读者敌人可点击左下角的「浏览原文」查看。
65 哥你听过「武当派」创始人张三疯么?Redis 主从架构就好比一个武当,掌门人就是 Master。掌门人如果挂了,须要从武当七侠外面选举能人担当掌门人。这就须要一个 部门 能监控掌门人的生死和武当其余弟子的生命状态,并且可能通过 投票 从武当弟子中选举一个能者负责新掌门,接着再举办新闻发布会向世界发表新掌门的信息。这个「部门」就是哨兵。
哨兵在选举新掌门会遇到以下几个问题:
- 如何判断掌门真的挂了,有可能假死;
- 到底抉择哪一个武当子弟作为新掌门?
- 通过新闻发布会将新掌门的相干信息告诉到所有 武当弟子(slave 和 master)和整个 武林(客户端)。
哨兵部门次要负责的工作是:监控整个武当、抉择新掌门,告诉整个武当和整个武林。
哨兵机制的次要工作
哨兵是 Redis 的一种运行模式,它专一于 对 Redis 实例(主节点、从节点)运行状态的监控,并可能在主节点产生故障时通过一系列的机制实现选主及主从切换,实现故障转移,确保整个 Redis 零碎的可用性。联合 Redis 的 官网文档,能够晓得 Redis 哨兵具备的能力有如下几个:
- 监控:继续监控 master、slave 是否处于预期工作状态。
- 主动切换主库:当 Master 运行故障,哨兵启动主动故障复原流程:从 slave 中抉择一台作为新 master。
- 告诉:让 slave 执行 replicaof,与新的 master 同步;并且告诉客户端与新 master 建设连贯。
哨兵也是一个 Redis 过程,只是不对外提供读写服务,通常哨兵要配置成单数,为啥呢?且听「码哥字节」缓缓剖析。
65 哥:那到底「哨兵」这个神秘部门是如何实现这三个能力的?
咱们先从全局观看哨兵,简要的理解整个运作流程,接着再针对每一个工作详细分析。首先从监控开始……
监控
Sentinel 只是武当弟子中的非凡部门,在默认状况下,Sentinel 通过飞鸽传书以每秒一次的频率向所有武当弟子、掌门与哨兵(包含 Master、Slave、其余 Sentinel 在内)发送 PING 命令,如果 slave 没有在在规定工夫内响应「哨兵」的 PING 命令,「哨兵」就认为这哥们可能嗝屁了,就会将他记录为「下线状态」;
如果 master 掌门没有在规定工夫响应「哨兵」的 PING 命令,哨兵就断定掌门下线,开始执行「主动切换 master 掌门」的流程。
PING 命令的回复有两种状况:
- 无效回复:返回 +PONG、-LOADING、-MASTERDOWN 任何一种;
- 有效回复:无效回复之外的回复,或者再指定工夫内返回任何回复。
65 哥:哨兵如何判断「掌门」嗝屁呢?掌门诈尸咋办?
为了避免掌门「假死」,「哨兵」设计了「主观下线」和「主观下线」两种暗号。
主观下线
哨兵利用 PING 命令来检测掌门、slave 的生命状态。如果是有效回复,哨兵就把这个哥们标记为「主观下线」。检测到的是武当小弟,也就是 slave 角色。那么就间接标记「主观下线」。
因为 master 掌门还在,slave 的嗝屁对整个武当影响不大。仍然能够对外散会,比武论剑、吃香喝辣……
如果检测到是 master 掌门完蛋,这时候哨兵不能这么简略的标记「主观下线」,开启新掌门选举。
因为有可能呈现误判,掌门并没有嗝屁,一旦启动了掌门切换,后续的选主、告诉开发布会,slave 花工夫与新 master 同步数据都会耗费大量资源。
所以「哨兵」要升高误判的概率,误判个别会产生在集群网络压力较大、网络拥塞,或者是主库自身压力较大的状况下。
既然一个人容易误判,那就多集体一起投票判断。哨兵机制也是相似的,采纳多实例组成的集群模式进行部署 ,这就是 哨兵集群。引入多个哨兵实例一起来判断,就能够防止单个哨兵因为本身网络情况不好,而误判主库下线的状况。
同时,多个哨兵的网络同时不稳固的概率较小,由它们一起做决策,误判率也能升高。
主观下线
判断 master 是否下线不能只有一个「哨兵」说了算,只有过半的哨兵判断 master 曾经「主观下线」,这时候能力将 master 标记为「主观下线」,也就是说这是一个客观事实,掌门真的嗝屁了,华佗再世也治不好了。
只有 master 被断定为「主观下线」,才会进一步触发哨兵开始主从切换流程。
主观下线与主观下线的区别
简略来说,主观下线是哨兵本人认为节点宕机,而主观下线是岂但哨兵本人认为节点宕机,而且该哨兵与其余哨兵沟通后,达到肯定数量的哨兵都认为该哥们嗝屁了。
这里的「肯定数量」是一个法定数量(Quorum),是由哨兵监控配置决定的,解释一下该配置:
# sentinel monitor <master-name> <master-host> <master-port> <quorum>
# 举例如下:
sentinel monitor mymaster 127.0.0.1 6379 2
这条配置项用于告知哨兵须要监听的主节点:
- sentinel monitor:代表监控。
- mymaster:代表主节点的名称,能够自定义。
- 192.168.11.128:代表监控的主节点 ip,6379 代表端口。
- 2:法定数量,代表只有两个或两个以上的哨兵认为主节点不可用的时候,才会把 master 设置为主观下线状态,而后进行 failover 操作。
「主观下线」的规范就是,当有 N 个哨兵实例时,要有 N/2 + 1 个实例判断 master 为「主观下线」,能力最终断定 Master 为「主观下线」,其实就是过半机制。
主动切换主库
65 哥:既然判断 master 主观下线了,那就要从选出一个新掌门人了吧。
「哨兵」的第二个工作,抉择新 master 掌门。须要从武当弟子中依照肯定规定抉择一个牛逼人物作为新掌门,实现选任掌门后,新 master 率领众弟子一起吃香喝辣。
依照肯定的 「筛选条件」+「打分」 策略,选出「最强王者」负责掌门,也就是通过一些条件海选过滤一些「无能之辈」,接着将通过海选的靓仔全都打分排名,将最高者选为新 master。
如图所示:
网络常常断开的靓仔也不可取,你想,即便变成 master,可是很快网络出了故障,又得从新抉择新 master,这不闹着玩么,得排除掉!
筛选条件
65 哥:那都有哪些筛选条件呀?
- 从库以后在线状态,下线的间接抛弃;
- 评估之前的网络连接状态 down-after-milliseconds * 10:如果从库总是和主库断连,而且断连次数超出了肯定的阈值(10 次),咱们就有理由置信,这个从库的网络情况并不是太好,就能够把这个从库筛掉了。
打分
过滤掉不适合的 slave 之后,则进入打分环节。打分会依照三个规定进行三轮打分,规定别离为:
- slave 优先级,通过 slave-priority 配置项,给不同的从库设置不同优先级(后盾有人没方法),优先级高的间接升级为新 master 掌门。
slave_repl_offset
与master_repl_offset
进度差距(谁的文治与之前掌门的功夫越靠近谁就更牛逼),如果都一样,那就持续下一个规定。其实就是比拟 slave 与旧 master 复制进度的差距;- slave runID,在优先级和复制进度都雷同的状况下,ID 号最小的从库得分最高,会被选为新主库。(论资排辈,依据 runID 的创立工夫来判断,工夫早的上位);
告诉
65 哥:为哈还要召开新闻发布会呢?
从新选举新 master 掌门这种事件,何等小事,怎能不告知天下。再者其余 slave 弟子也要晓得新掌门是谁,一起追寻新掌门吃香喝辣大保健。
最初一个工作,「哨兵」将新「master 掌门」的连贯信息发送给其余 slave 武当弟子,并且让 slave 执行 replacaof 命令,和新「master 掌门」建设连贯,并进行数据复制学习新掌门的所有文治。
除此之外,「哨兵」还须要将新掌门的连贯信息告诉整个武林(客户端),使得让所有想访问、请教的人能找到新任掌门,这样诸多事宜能力交给新掌门做决定(将读写申请转移到新 master)。
哨兵的次要工作与实现目标
哨兵集群工作原理
「哨兵」部门并不是一个人,多集体独特组成一个「哨兵集群」,即便有一些「哨兵」被老王打死了,其余的「哨兵」仍然能够独特合作实现监控、新掌门选举以及告诉 slave、master 以及每一个武林人士(客户端)。
在配置哨兵集群的时候,哨兵配置中只设置了监控的 master IP 和 port,并没有配置其余哨兵的连贯信息。
sentinel monitor <master-name> <ip> <redis-port> <quorum>
哨兵之间是如何晓得彼此的?如何晓得 slave 并监控他们的?由哪一个「哨兵」执行主从切换呢?
带着这些问题,跟着「码哥字节」一起寻根究底,深刻哨兵集群心脏。
pub/sub 实现哨兵间通信和发现 slave
65 哥:哨兵之间是如何晓得彼此的?
哨兵之间能够互相通信约会搞事件,次要归功于 Redis 的 pub/sub
公布 / 订阅机制。
哨兵与 master 建设通信,利用 master 提供公布 / 订阅机制公布本人的信息,比方身高体重、是否独身、IP、端口……
master 有一个 __sentinel__:hello
的专用通道,用于哨兵之间公布和订阅音讯。这就好比是 __sentinel__:hello
微信群,哨兵利用 master 建设的微信群公布本人的音讯,同时关注其余哨兵公布的音讯。
当多个哨兵实例都在主库上做了公布和订阅操作后,它们之间就能晓得彼此的 IP 地址和端口,从而互相发现建设连贯。
Redis 通过频道的形式对音讯进行别离治理,这里的频道其实就是不同的微信群。比方“码哥字节读者技术群”就是专门 分享技术 的群。敌人们能够关注公众号,后盾回复“加群”,一起成长。
65 哥:哨兵之间尽管建设连贯了,然而还须要和 slave 建设连贯,不然没法监控他们呀,如何晓得 slave 并监控他们的?
确实,哨兵之间建设连贯造成集群还不够,还须要跟 slave 建设连贯,不然没法监控他们,无奈对主从库进行心跳判断。
除此之外,如果产生了主从切换也得告诉 slave 从新跟新 master 建设连贯执行数据同步。对于主从架构数据同步原理可移步《Redis 高可用篇:你管这叫主从架构数据一致性同步》。
要害还是利用 master 来实现,哨兵向 master 发送 INFO
命令,master 掌门天然是晓得本人门下所有的 salve 小弟的。所以 master 接管到命令后,便将 slave 列表通知哨兵。
哨兵依据 master 响应的 slave 名单信息与每一个 salve 建设连贯,并且依据这个连贯继续监控哨兵。
如图所示,哨兵 2 向 Master 发送 INFO
命令,Master 就把 slave 列表返回给哨兵 2,哨兵 2 便依据 slave 列表连贯信息与每一个 slave 建设连贯,并基于此连贯实现继续监控。
剩下的哨兵也同理基于此实现监控。
抉择哨兵执行主从切换
65 哥:master 嗝屁了当前,哨兵这么多,那到底让哪一个哨兵来执行新 master 切换呢?
这个跟哨兵判断 master“主观下线”相似,也是通过投票的形式选出来的。
任何一个哨兵判断 master“主观下线”后,就会给其余哨兵基友发送 is-master-down-by-addr
命令,好基友则依据本人跟 master 之间的连贯情况别离响应 Y
或者 N
,Y
示意赞成票,N
就是拥护。
如果某个哨兵取得了大多数哨兵的“赞成票”之后,就能够标记 master 为“主观下线”,赞成票数是通过哨兵配置文件中的 quorum 配置项设定。
sentinel monitor <master-name> <ip> <redis-port> <quorum>
比方一共 3 个哨兵组成集群,那么 quorum 就能够配置成 2,当一个哨兵取得了 2 张赞成票,就能够标记 master“主观下线”,当然这个票蕴含本人的那一票。
取得少数赞成票的哨兵能够向其余哨兵发送命令,申明本人想要执行主从切换。并让其余哨兵进行投票,投票过程就叫做“Leader 选举”。
想要成为“Leader”没那么简略,得有两把刷子。须要满足以下条件:
- 取得其余哨兵基友过半的赞成票;
- 赞成票的数量还要 大于等于 配置文件的 quorum 的值。
如果哨兵集群有 2 个实例,此时,一个哨兵要想成为 Leader,必须取得 2 票,而不是 1 票。所以,如果有个哨兵挂掉了,那么,此时的集群是无奈进行主从库切换的。因而,通常咱们至多会配置 3 个哨兵实例。
这也是为啥哨兵集群部署成单数的起因,单数的话多余节约。
选举流程如下图所示:
通过 pub/sub 实现客户端事件告诉
65 哥:新 master 选出来了,要怎么公示天下呢?
当然是召开新闻发布会呀,邀请音讯相干类型的媒体报道流传,感兴趣的人天然就去关注订阅相干事件,并依据事件做出口头。
在 Redis 也是相似,通过 pub/sub 机制公布不同事件,让客户端在这里订阅音讯。客户端能够订阅哨兵的音讯,哨兵提供的音讯订阅频道有很多,不同频道蕴含了主从库切换过程中的不同要害事件。
也就是在不同的“微信群”公布不同的事件,让对该事件感兴趣的人进群即可。
master 下线事件
- +sdown:进入“主观下线”状态;
- -sdown:退出“主观下线”状态;
- +odown:进入“主观下线”状态;
- -odown:退出“主观下线”状态;
slave 重新配置事件
- +slave-reconf-sent:哨兵发送 replicaof 命令重新配置从库;
- +slave-reconf-inprog:slave 配置了新 master,然而尚未进行同步;
- +slave-reconf-done:slave 配置了新 master,并与新 master 实现了数据同步;
新主库切换
+switch-master:master 地址产生了变动。
晓得了这些频道之后,就能够让客户端从哨兵这里订阅音讯了。客户端读取哨兵的配置文件后,能够取得哨兵的地址和端口,和哨兵建设网络连接。
而后,咱们能够在客户端执行订阅命令,来获取不同的事件音讯。
举个栗子:如下指令订阅“所有实例进入主观下线状态的事件”
SUBSCRIBE +odown
注意事项与配置阐明
发现了没,Redis 的 pub/sub 公布订阅机制尤其重要,有了 pub/sub 机制,哨兵和哨兵之间、哨兵和从库之间、哨兵和客户端之间就都能建设起连贯了,各种事件的公布也是通过这个机制实现。
down-after-milliseconds
Sentinel 配置文件中的 down-after-milliseconds 选项指定了 Sentinel 判断实例进入主观下线所需的工夫长度:如果一个实例在 down-after-milliseconds 毫秒内,间断向 Sentinel 返回有效回复,那么 Sentinel 会批改这个实例所对应数据,以此来示意这个实例曾经进入主观下线状态。
要保障所有哨兵实例的配置是统一的,尤其是主观下线的判断值 down-after-milliseconds。因为这个值在不同的哨兵实例上配置不统一,导致哨兵集群始终没有对有故障的主库造成共识,也就没有及时切换主库,最终的后果就是集群服务不稳固。
down-after-milliseconds * 10
down-after-milliseconds 是咱们认定主从库断连的最大连贯超时工夫。如果在 down-after-milliseconds 毫秒内,主从节点都没有通过网络分割上,咱们就能够认为主从节点断连了。如果产生断连的次数超过了 10 次,就阐明这个从库的网络情况不好,不适宜作为新主库。
总结
哨兵次要工作
Redis 哨兵机制是实现 Redis 不间断服务的高可用伎俩之一。主从架构集群的数据同步,是数据牢靠的根底保障;主库宕机,主动执行主从切换是服务不间断的要害撑持。
Redis 哨兵机制实现了主从库的主动切换,再也不怕跟女盆友么么哒的时候 master 宕机了:
- 监控 master 与 slave 运行状态,判断是否主观下线;
- master 主观下线后,抉择一个 slave 切换成 master;
- 告诉 slave 和客户端新 master 信息。
哨兵集群原理
为了防止单个哨兵故障后无奈进行主从切换,以及为了缩小误判率,又引入了哨兵集群;哨兵集群又须要有一些机制来撑持它的失常运行:
- 基于 pub/sub 机制实现哨兵集群之间的通信;
- 基于 INFO 命令获取 slave 列表,帮忙 哨兵与 slave 建设连贯;
- 通过哨兵的 pub/sub,实现了与客户端和哨兵之间的事件告诉。
主从切换,并不是随便抉择一个哨兵就能够执行,而是通过投票仲裁,抉择一个 Leader,由这个 Leader 负责主从切换。
一起交换
下一篇「码哥字节」将带来 《Redis 高可用篇:Cluster 集群,是兄弟就跟我一起扛》,关注我,获取真正的硬核知识点。
另外技术 读者群 也开明了,后盾回复「加群」获取「码哥字节」作者微信交换或者提出倡议,一起成长交换。群里有 N 多大厂的大佬,也可内推哦。
以上就是 Redis 哨兵集群原理详解,感觉不错请点赞、分享,「码哥字节」感激不尽。
参考资料
- [1] [redis 设计与实现] 黄健宏
- [2] [redis 核心技术与实战] https://time.geekbang.org/column/article/274483
- [3] [redis 深度历险:外围原理与利用实战] https://juejin.cn/book/6844733724618129422/section/6844733724722987021
- [4] [redis 专题:深刻解读哨兵模式] https://juejin.cn/post/6934984432273063967#heading-0
- [5] [redis 哨兵原理,我忍你很久了!] https://www.modb.pro/db/25926