Redis - 哨兵模式 sentinel + 故障转移 failover + 哨兵选举 + 脑裂现象

一、哨兵模式概述

哨兵模式的 redis 集群有三种角色:sentinel/master/slave,它们通过 tcp 链接,相互建立联系。

sentinel 作为高可用集群管理者,它的功能主要是:检查故障,发现故障,故障转移。

 

 

 

1.1 单哨兵模式 - 不推荐

 

 

 

 

1.2 多哨兵模式 - 故障转移failover流程(重点)

  1. 在 redis 集群中,当 sentinel 检测到 master(redis 主服务)出现故障,那么 sentinel 需要对集群进行故障转移。
  2. 当一个 sentinel 发现 master 下线,它会将下线的 master 确认为主观下线
  3. 当“法定个数”(quorum)sentinel 已经发现该 master 节点下线,那么 sentinel 会将其确认为客观下线
  4. 多个 sentinel 根据一定的逻辑(详见1.3 多哨兵模式 - sentinel哨兵选举规则),选举出一个 sentinel 作为 leader
  5. 由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 选举的法定人数。

  1. sentinel 节点个数最好 >= 3。
  2. sentinel 节点个数最好是基数。
  3. 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编辑  收藏  举报

导航

levels of contents