关于java:redis高可用redis哨兵集群

2次阅读

共计 3869 个字符,预计需要花费 10 分钟才能阅读完成。

1. 哨兵的介绍

sentinel,中文名是哨兵。哨兵是 redis 集群机构中十分重要的一个组件,次要有以下性能:

  • 集群监控:负责监控 redis master 和 slave 过程是否失常工作。
  • 音讯告诉:如果某个 redis 实例有故障,那么哨兵负责发送音讯作为报警告诉给管理员。
  • 故障转移:如果 master node 挂掉了,会主动转移到 slave node 上。
  • 配置核心:如果故障转移产生了,告诉 client 客户端新的 master 地址。

哨兵用于实现 redis 集群的高可用,自身也是分布式的,作为一个哨兵集群去运行,相互协同工作。

故障转移时,判断一个 master node 是否宕机了,须要大部分的哨兵都批准才行,波及到了分布式选举的问题。
即便局部哨兵节点挂掉了,哨兵集群还是能失常工作的,因为如果一个作为高可用机制重要组成部分的故障转移零碎自身是单点的,那就很坑爹了。

2. 哨兵的外围常识

哨兵至多须要三个实例能力保障健壮性。
哨兵 + redis 主从的部署架构,是不保证数据零失落的,只能保障 redis 集群的高可用性。
对于哨兵 + redis 主从这种简单的部署架构,尽量在测试环境和生产环境,都进行短缺的测试和演练。

哨兵集群必须部署 2 个以上节点,如果哨兵集群仅仅部署了 2 个哨兵实例,quorum = 1。

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+

配置 quorum=1,如果 master 宕机,s1 和 s2 中只有有 1 个哨兵认为 master 宕机了,就能够进行切换,同时 s1 和 s2 会选举出一个哨兵来执行故障转移。然而同时这个时候,须要 majority,也就是大多数哨兵都是运行的。

  2 个哨兵,majority=2
  3 个哨兵,majority=2
  4 个哨兵,majority=2
  5 个哨兵,majority=3
  ...
  

如果此时仅仅是 M1 过程宕机了,哨兵 s1 失常运行,那么故障转移是 OK 的。然而如果是整个 M1 和 S1 运行的机器宕机了,那么哨兵只有 1 个,此时就没有 majority 来容许执行故障转移,尽管另外一台机器上还有一个 R1,然而故障转移不会执行。

经典的 3 节点哨兵集群是这样的:

       +----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+

配置 quorum=2,如果 M1 所在机器宕机了,那么三个哨兵还剩下 2 个,S2 和 S3 能够统一认为 master 宕机了,而后选举出一个来执行故障转移,同时 3 个哨兵的 majority 是 2,所以还剩下的 2 个哨兵运行着,就能够容许执行故障转移。

3. redis 哨兵主备切换的数据失落问题

两种状况会导致数据失落:

  • 异步复制导致的数据失落
    因为 master->slave 的复制是异步的,所以可能有局部数据还没复制到 slave,master 就宕机了,此时这部分数据就失落了。
  • 脑裂导致的数据失落
    脑裂,也就是说,某个 master 所在机器忽然脱离了失常的网络,跟其余 slave 机器不能连贯,然而实际上 master 还运行着。此时哨兵可能就会认为 master 宕机了,而后开启选举,将其余 slave 切换成了 master。这个时候,集群里就会有两个 master,也就是所谓的脑裂。

此时尽管某个 slave 被切换成了 master,然而可能 client 还没来得及切换到新的 master,还持续向旧 master 写数据。因而旧 master 再次复原的时候,会被作为一个 slave 挂到新的 master 下来,本人的数据会清空,从新从新的 master 复制数据。而新的 master 并没有起初 client 写入的数据,因而,这部分数据也就失落了。

###4. 数据失落问题的解决方案
进行如下配置:

  min-slaves-to-write 1
  min-slaves-max-lag 10

示意,要求至多有 1 个 slave,数据复制和同步的提早不能超过 10 秒。

如果说一旦所有的 slave,数据复制和同步的提早都超过了 10 秒钟,那么这个时候,master 就不会再接管任何申请了。

  • 缩小异步复制数据的失落
    有了 min-slaves-max-lag 这个配置,就能够确保说,一旦 slave 复制数据和 ack 延时太长,就认为可能 master 宕机后损失的数据太多了,那么就回绝写申请,这样能够把 master 宕机时因为局部数据未同步到 slave 导致的数据失落升高的可控范畴内。
  • 缩小脑裂的数据失落
    如果一个 master 呈现了脑裂,跟其余 slave 丢了连贯,那么下面两个配置能够确保说,如果不能持续给指定数量的 slave 发送数据,而且 slave 超过 10 秒没有给本人 ack 音讯,那么就间接回绝客户端的写申请。因而在脑裂场景下,最多就失落 10 秒的数据。

5.sdown 和 odown 转换机制

sdown 是主观宕机,就一个哨兵如果本人感觉一个 master 宕机了,那么就是主观宕机
odown 是主观宕机,如果 quorum 数量的哨兵都感觉一个 master 宕机了,那么就是主观宕机
sdown 达成的条件很简略,如果一个哨兵 ping 一个 master,超过了 is-master-down-after-milliseconds 指定的毫秒数之后,就主观认为 master 宕机了;如果一个哨兵在指定工夫内,收到了 quorum 数量的其它哨兵也认为那个 master 是 sdown 的,那么就认为是 odown 了。

6. 哨兵集群的主动发现机制

哨兵相互之间的发现,是通过 redis 的 pub/sub 零碎实现的,每个哨兵都会往 __sentinel__:hello 这个 channel 里发送一个音讯,这时候所有其余哨兵都能够生产到这个音讯,并感知到其余的哨兵的存在。每隔两秒钟,每个哨兵都会往本人监控的某个 master+slaves 对应的 __sentinel__:hello channel 里发送一个音讯,内容是本人的 host、ip 和 runid 还有对这个 master 的监控配置。每个哨兵也会去监听本人监控的每个 master+slaves 对应的 __sentinel__:hello channel,而后去感知到同样在监听这个 master+slaves 的其余哨兵的存在。每个哨兵还会跟其余哨兵替换对 master 的监控配置,相互进行监控配置的同步。

7.slave 配置的主动纠正

哨兵会负责主动纠正 slave 的一些配置,比方 slave 如果要成为潜在的 master 候选人,哨兵会确保 slave 复制现有 master 的数据;如果 slave 连贯到了一个谬误的 master 上,比方故障转移之后,那么哨兵会确保它们连贯到正确的 master 上。

8.slave->master 选举算法

如果一个 master 被认为 odown 了,而且 majority 数量的哨兵都容许主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个 slave 来,会思考 slave 的一些信息:

跟 master 断开连接的时长
slave 优先级
复制 offset
run id
如果一个 slave 跟 master 断开连接的工夫曾经超过了 down-after-milliseconds 的 10 倍,外加 master 宕机的时长,那么 slave 就被认为不适宜选举为 master。

(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
Copy to clipboardErrorCopied
接下来会对 slave 进行排序:

依照 slave 优先级进行排序,slave priority 越低,优先级就越高。
如果 slave priority 雷同,那么看 replica offset,哪个 slave 复制了越多的数据,offset 越靠后,优先级就越高。
如果下面两个条件都雷同,那么抉择一个 run id 比拟小的那个 slave。

9.quorum 和 majority

每次一个哨兵要做主备切换,首先须要 quorum 数量的哨兵认为 odown,而后选举出一个哨兵来做切换,这个哨兵还须要失去 majority 哨兵的受权,能力正式执行切换。

如果 quorum < majority,比方 5 个哨兵,majority 就是 3,quorum 设置为 2,那么就 3 个哨兵受权就能够执行切换。

然而如果 quorum >= majority,那么必须 quorum 数量的哨兵都受权,比方 5 个哨兵,quorum 是 5,那么必须 5 个哨兵都批准受权,能力执行切换。

10.configuration epoch

哨兵会对一套 redis master+slaves 进行监控,有相应的监控的配置。

执行切换的那个哨兵,会从要切换到的新 master(salve->master)那里失去一个 configuration epoch,这就是一个 version 号,每次切换的 version 号都必须是惟一的。

如果第一个选举出的哨兵切换失败了,那么其余哨兵,会期待 failover-timeout 工夫,而后接替继续执行切换,此时会从新获取一个新的 configuration epoch,作为新的 version 号。

11.configuration 流传

哨兵实现切换之后,会在本人本地更新生成最新的 master 配置,而后同步给其余的哨兵,就是通过之前说的 pub/sub 音讯机制。

这里之前的 version 号就很重要了,因为各种音讯都是通过一个 channel 去公布和监听的,所以一个哨兵实现一次新的切换之后,新的 master 配置是跟着新的 version 号的。其余的哨兵都是依据版本号的大小来更新本人的 master 配置的。

正文完
 0