Redis - 哨兵模式 sentinel + 故障转移 failover + 哨兵选举 + 脑裂现象
一、哨兵模式概述
哨兵模式的 redis 集群有三种角色:sentinel/master/slave,它们通过 tcp 链接,相互建立联系。
sentinel 作为高可用集群管理者,它的功能主要是:检查故障,发现故障,故障转移。
1.1 单哨兵模式 - 不推荐
1.2 多哨兵模式 - 故障转移failover流程(重点)
- 在 redis 集群中,当 sentinel 检测到 master(redis 主服务)出现故障,那么 sentinel 需要对集群进行故障转移。
- 当一个 sentinel 发现 master 下线,它会将下线的 master 确认为主观下线。
- 当“法定个数”(quorum)sentinel 已经发现该 master 节点下线,那么 sentinel 会将其确认为客观下线。
- 多个 sentinel 根据一定的逻辑(详见1.3 多哨兵模式 - sentinel哨兵选举规则),选举出一个 sentinel 作为 leader
- 由sentinel leader去进行故障转移,将原来连接已客观下线 master 最优的一个 slave 提升为新 master 角色。旧 master 如果重新激活,它将被降级为 slave。
1.3 多哨兵模式 - sentinel哨兵选举规则 (重点)
- 每个在线的sentinel节点都可以成为领导者leader sentinel。当某个sentinel确认redis主服务master下线时,会向其他sentinel 哨兵发 is-master-down-by-addr 命令,征求判断并要求将自己设置为领导者,由领导者处理故障转移;
- 当其他哨兵收到此命令时,可以同意或者拒绝它成为领导者;
- 如果竞争成为leader的sentinel哨兵,发现自己在选举的票数大于等于哨兵的个数/2+1时,并且其数量也超过了设定的quoram参数,将会成为领导者。如果没有超过,或者多个哨兵同时参与这个选举,那么就会重复该过程,直到选出一个leader领头sentinel哨兵。
1.4 哨兵模式优缺点
二、脑裂现象
2.1 什么是脑裂?
所谓脑裂问题(类似于精神分裂),就是同一个集群中的不同节点,对于集群的状态有了不一样的理解。
2.2 哨兵模式如何造成脑裂现象?
redis集群的三个角色:
- M :redis 主服务 master
- R :redis 副本 replication/slave
- S :redis 哨兵 sentinel
sentinel 配置 quorum = 1
,也就是一个 sentinel 发现故障,也可以选举自己为 leader,进行故障转移。
下面的部署:两个机器,分别部署了 redis 的三个角色
+----+ +----+ | M1 |---------| R1 | | S1 | | S2 | +----+ +----+
因为某种原因,两个机器断开链接,S2 将同机器的 R1 提升角色为 master,这样集群里,出现了两个 master 同时工作 —— 脑裂出现了。不同的 client 链接到不同的 redis 进行读写,那么两台机器就出现了 redis 数据不一致的现象。
+----+ +------+ | M1 |----//-----| [M1] | | S1 | | S2 | +----+ +------+
2.3 怎么解决脑裂现象?
通过合理部署配置 sentinel/master,降低脑裂出现概率。
通过sentienl 配置解决
合理部署 sentinel 的节点个数,以及配置 sentinel 选举的法定人数。
- sentinel 节点个数最好 >= 3。
- sentinel 节点个数最好是基数。
- sentinel 的选举法定人数设置为 (n/2 + 1)。
配置
# sentinel.conf
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
quorum
- <quorum> 是
法定人数
。作用:多个 sentinel 进行相互选举,有超过法定人数
的 sentinel 选举某个 sentinel 为 leader,那么他就成为 leader, leader 负责故障转移。这个法定人数,可以配置,一般是 sentinel 个数一半以上 (n/2 + 1) 比较合理。 - 如果 sentinel 个数总数为 3,那么最好 quorum == 2,这样最接近真实:少数服从多数,不会出现两个票数一样的 leader同时被选上,进行故障转移。
# sentinel.conf sentinel monitor mymaster >127.0.0.1 6379 2
通过master 配置解决
如果 master 因为某些原因与一定数量的副本失去联系了,通过修改 master 配置项,可以禁止 client 向故障的 master 写数据。
1. 依然存在的问题
按照上述的 sentinel 部署方案,下面三个机器,任何一个机器出现问题,只要两个 sentinel 能相互链接,故障转移是正常的。
+----+ | M1 | | S1 | +----+ | +----+ | +----+ | R2 |----+----| R3 | | S2 | | S3 | +----+ +----+ Configuration: quorum = 2
假如 M1 机器与其它机器断开链接了,S2 和 S3 两个 sentinel 能相互链接,sentinel 能正常进行故障转移,sentinel leader 将 R2 提升为新的 master 角色 [M2]。但是客户端 C1 仍然能读写 M1,这样仍然会出现问题,所以我们不得不对 M1 进行限制。
+----+
| M1 |
| S1 | <- C1 (writes will be lost)
+----+
|
/
/
+------+ | +----+
| [M2] |----+----| R3 |
| S2 | | S3 |
+------+ +----+
2.解决方案
限制 M1 比较简单的方案,通过修改 redis 配置 redis.conf,检查 master 节点与其它副本的联系。当 master 发现它的副本下线或者通信超时的总数量小于阈值时,那么禁止 master 进行写数据。
但是这个方案也不是完美的,min-slaves-to-write 依赖于副本的链接个数,如果 slave 个数设置不合理,那么集群很难故障转移成功。
redis.conf配置
# master 须要有至少 x 个副本连接。 min-slaves-to-write x # 数据复制和同步的延迟不能超过 x 秒。 min-slaves-max-lag x
测试
测试 - 单哨兵模式
最后的“1”,代表当“1”的哨兵认为主机宕机时,该主机才被判定为宕机。如果配置了多哨兵模式,比如三个哨兵,该数字一般会设置为2、3.
1. 哨兵配置文件
2. 启动哨兵
测试 - 多哨兵模式
posted on 2021-04-19 16:52 frank_cui 阅读(2765) 评论(0) 编辑 收藏 举报