首页 > 首页 > 数据库 > 非关系型数据库 > Redis > Redis 架构原理02:深入理解redis cluster的failover机制
2024
09-10

Redis 架构原理02:深入理解redis cluster的failover机制

基础概念

redis cluster是无中心节点P2P的集群架构,内部采用gossip协议传递维护集群的拓扑结构和集群元数据。社区文档地址: https://redis.io/topics/cluster-tutorial

Redis 架构原理02:深入理解redis cluster的failover机制 - 第1张  | 架构迷

failover是redis cluster提供的容错机制,cluster最核心的功能之一。failover支持两种模式:

  • 故障failover:自动恢复集群的可用性
  • 人为failover:支持集群的可运维操作

1、故障failover

故障failover表现在一个master分片故障后,slave接管master的过程。

1.1、探测阶段

集群中的所有分片通过gossip协议传递。探测步骤为:

(1)在cron中非遍历cluster nodes做ping发送,随机从5个节点中选出最老pong_recv的节点发送ping,再遍历节点中pong_recv > timeout/2的节点发送ping。

(2)再遍历每个节点从发出ping包后超时没有收到pong包的时间,超时将对应的分片设置为pfail状态,在跟其他节点的gossip包过程中,每个节点会带上被标记为pfail状态的包。

(3)每个正常分片收到ping包后,统计集群中maste分片将故障节点设置为pfail, 超过一半以上的节点设置为pfail, 则将节点设置为fail状态。如果这个分片属于故障节点的slave节点,则主动广播故障节点为fail状态。

下图以3个节点集群来说明核心的流程:

Redis 架构原理02:深入理解redis cluster的failover机制 - 第2张  | 架构迷

1.2、准备阶段

在cron函数中,slave节点获取到master节点状态为fail,主动发起一次failover操作,该操作并不是立即执行,而是设计了多个限制:

(1)过期的超时不执行。如何判断是够过期? data_age = 当前时间点-上次master失联的时间点-超时时间

如果data_age > master到slave的ping间隔时间+超时时间*cluster_slave_validity_factor, 则认为过期。cluster_slave_validity_factor是一个配置项,cluster_slave_validity_factor 设置的越小越不容易触发failover。

(2)计算出一个延迟执行的时间failover_auth_time, failover_auth_time = 当前时间 + 500ms + 0-500ms的随机值 + 当前slave的rank*1s,  rank按已同步的offset计算,offset同步的越延迟,rank值越大,该slave 就越推迟触发failover的时间,以此来避免多个slave同时failover。只有当前时间到failover_auth_time的时间点才会执行failover。

1.3、执行阶段

(1)将currentEpoch自增,再赋值给failover_auth_epoch

(2)向其他master分片发起failover投票,等待投票结果

(3)其他master分片收到CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST请求后,会判断是否符合以下情况:

  • epoch必须>=所有集群视图的master节点的epoch
  • 发起者是slave
  • slave的master已是fail状态
  • 在相同epoch内只投票一次
  • 在超时时间(cluster_node_timeout)* 2的时间内只投票一次

(4)其他master回复CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK,slave端收到后做统计

(5)在cron中判断统计超过一半以上master回复,开始执行failover

(6)标记自身节点为master

(7)清理复制链路

(8)重置集群拓扑结构信息

(9)向集群内所有节点广播

下图以3个节点集群来说明核心的流程:

Redis 架构原理02:深入理解redis cluster的failover机制 - 第3张  | 架构迷

2、人为failover

人为failover支持三种模式的failover:缺省、force、takeover。

2.1、缺省

(1)给master 发送CLUSTERMSG_TYPE_MFSTART

(2)master收到后设置clients_pause_end_time = 当前时间+ 5s*2,clients_paused =1 ,客户端暂停所有请求,新建请求会被加到block client list。

(3)master在ping包中带上repl_offset的信息

(4)slave检查master的repl_offset,确认同步已完成

(5)设置mf_can_start = 1,在cron中开始正常的failover流程,不需要像故障failover设置推迟执行而是立即执行操作, 而且其他master投票时不需要考虑master是否为fail状态。

Redis 架构原理02:深入理解redis cluster的failover机制 - 第4张  | 架构迷

2.2、force

忽略主备同步的状态,设置mf_can_start = 1,标记failover开始。

2.3、takeover

直接执行故障failover的第6-9步,忽略主备同步,忽略集群其他master的投票。

原文地址:https://developer.aliyun.com/article/638627

最后编辑:
作者:摘星怪
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。