Redis Cluster的FailOver失败案例分析

本文详细解析了RedisCluster中故障转移的工作原理,包括失败判定与Leader选举机制,并针对大规模集群中故障转移失败的问题进行了深入分析及解决。

场景:
      使用redis clusterRC1部署集群,6台机器,每台部署16个实例,每个master使用一个slave,node_timeout为默认值(15s)。kill掉其中一个master发现failover完成不了。通过cluster nodes观察,该节点一直处于pfail状态。问题出在失败判定上,一直处于PFail,说明完成不了PFail->Fail的转换。然而同样的配置在32节点的集群中,Failover一点问题没有。
FailOver设计实现:
      Failover,通俗地说,一个master有N(N>=1)个slave,当master挂掉以后,能选出一个slave晋升成Master继续提供服务。Failover由失败判定和Leader选举两部分组成,Redis Cluster采用去中心化(Gossip)的设计,每个节点通过发送Ping(包括Gossip信息)/Pong心跳的方式来探测对方节点的存活,如果心跳超时则标记对方节点的状态为PFail,这个意思是说该节点认为对方节点可能失败了,有可能是网络闪断或者分区等其他原因导致通讯失败。例如节点A给节点B发Ping/Pong心跳超时,则A将B标记为PFAIL,强调一点,仅是在A看来B节点失败。要完全判定B失败,则需要一种协商的方式,需要集群中一半以上的Master节点认为B处于PFail状态,才会正式将节点B标记为Fail。那么问题来了,Master之间如何交换意见呢,或者说节点A如何知道其他Master也将B标记为PFfail了,并且能统计出是否有一半以上的Master认为B为PFail呢?前面提到Gossip,Gossip的主要作用就是信息交换,在A给C发Ping的时候,A将已知节点随机挑选三个节点添加到Ping包中发给C。既然是随机,经过多次Gossip以后,A会将处于PFail的B告诉给C。在节点C上,B节点有一个失败报告的链表,A告诉C,B可能失败,将A节点添加到B节点的失败报告链表中。经过集群中所有节点之间多次Gossip,一旦B的失败报告数量超过Master数量的一半以上,就立即标记B为Fail并广播给整个集群。那这样还会有一个问题,假设一天之内失败报告的数量超过Master的一半以上,同时报告的时间间隔又比较大,那么就会产生误判。所以得给失败报告加上一个有效期,在一定的时间窗口内,失败报告的数量超过Master的一半以上以后标记为Fail,这样才能避免误判。至此就把失败判定说完了,剩下还有Leader选举,Redis Cluster采用类似Raft的算法,有一点不同的是并不是slave之间进行投票,而是在所有Master中间进行投票。这样做的好处就是即使一主一从也能完成选举,Redis Cluster这样做也是有道理。slave不提供任务服务,如果允许挂N个节点,就得部署(2N+1)个slave,这是资源的极大浪费。Leader选举和主题不太相关就不细讲了,我写了一个PPT讲Redis Cluster的Failover设计(http://vdisk.weibo.com/s/u78RGlrhC7FF/1422958608)。
问题定位:
      看完上面的FailOver设计实现,问题就不难定位了。在时间窗口内,失败报告的数量没有达到Master的一半以上,所以完成不了Pfail到Fail的转换。Redis Cluster的这个时间窗口是cluster-node-timeout *  REDIS_CLUSTER_FAIL_REPORT_VALIDITY_MULT,其中REDIS_CLUSTER_FAIL_REPORT_VALIDITY_MULT=2,是一个常量,不能修改。那么默认的失败报告有效期是30s,在30s内不能收集到Master的一半以上的失败报告,新加入的失败报告赶不上失效的速度,所以一直完不成PFail到Fail的转换,这就是问题所在。我首先想到调大REDIS_CLUSTER_FAIL_REPORT_VALIDITY_MULT到10,Failover能成功了,但耗时过长至少要在60s以上,并且不知要调大了有没有副作用,就提了一个issue(https://github.com/antirez/redis/issues/2285)给作者 。作者看了以后,不确定副作用,但他觉得需要一个更加通用的解决方案。其实调大这个参数只是治标不治本,问题的根源是Gossip太慢了,随机挑选3个节点,并且选中PFail的节点还需要有一定的概率。是不是可以优先考虑从PFail的节点集合中随机选出一部分,再从正常节点中选出一部分,这就兼顾了PFail和新加入的节点,就又提了个issue(https://github.com/antirez/redis/issues/2336)。作者先做了一个调整,Gossip携带节点的数量不再是3而是集群规模的1/10,他认为1/10是一个魔数,具体原因在cluster.c的clusterSendPing函数中有描述。然后在这个版本上进行测试,修改cluster-node-timeout为5s,发现Master的失败判定只需要12s,这个时间包括PFail的标记和PFai->Fail的转换。然而slave的失败判定就不是很稳定了在20~70s之间。我觉得还不是很理想,作者说他测试的结果比我的要理想很多,并且说他又做了一些优化,还是先发布RC3吧。我比对了RC3和我测试版本的区别,发现作者在Gossip的时候添加对PFail或Fail节点的偏好,我重新在RC3上测试,结果很理想,Master失败判定需要9s,Slave需要11s并且很稳定。

结论:
      如果在较大规模的RedisCluster集群上遇到这个问题,果然地升级RC3吧。


源自:http://xiaoz5919.iteye.com/blog/2183833

<think> 嗯,用户这次聚焦在Redis Cluster集群的备份必要性上,看来是在生产环境遇到了实际运维决策。之前讨论普通Redis缓存备份时用户应该已经理解基础逻辑,现在需要更针对集群架构的特性分析。 用户提供的引用材料很有价值,尤其引用[4]提到Redis Cluster的异步复制特性——这直接关系到灾备设计。需要特别注意:即使集群有主从复制,异步机制仍可能导致写入丢失(master写入成功但未同步到slave时宕机)。用户可能担心单纯依赖集群内复制是否足够。 从运维角度看(引用[3]),用户所在团队似乎正在推进缓存系统统一化,这种标准化过程中备份策略必须纳入考量。引用[2]的集群升级示例也暗示了槽位信息记录的重要性,这其实属于备份范畴——不仅要备数据,还要备元数据。 用户没明说但可能纠结的点在于:Cluster本身有高可用机制(slave自动切换),是否还需额外备份?这里要分两层回应: 1)硬件或地域故障层面:单机房集群的所有节点可能同时失效; 2)数据逻辑层面:误操作删除或程序bug污染数据时,集群复制只会同步错误数据。 想到个典型案例:某电商大促前误执行`FLUSHALL`,如果没有离线备份,即使集群所有节点健在,数据也瞬间归零。 回复时需要强调三个关键动作: - 定期远程备份RDB(尽管Cluster分散数据,但redis-cli --cluster backup可整合) - 验证备份文件可恢复性(模拟slot分配) - 和业务方确认数据再生成本(有些推荐模型生成耗时数小时) 最后补充的运维建议要实用,比如备份文件命名规则最好包含槽位分布版本号(参考引用[2]的槽位记录要求)。 </think> Redis Cluster缓存集群**必须进行备份**,即使它作为缓存层使用。以下是核心分析及解决方案: --- ### 一、必须备份的关键原因 1. **数据不可再生风险** - 部分缓存数据(如实时计算的聚合结果、用户会话)丢失后无法从数据库直接重建,需耗时重新计算[^4]。 - **场景示例**:推荐系统缓存丢失,导致瞬时计算压力击垮服务。 2. **集群高可用≠数据安全** - Redis Cluster的主从切换(Failover)仅解决节点故障,无法防御: - 误操作(如`FLUSHALL`) - 程序Bug导致数据污染 - 物理灾难(机房火灾)[^1][^3] - 异步复制下,写入成功的请求仍可能丢失(引用[4]明确说明) 3. **持久化机制局限性** - RDB快照默认间隔5分钟,期间数据可能丢失。 - AOF日志文件可能损坏(如磁盘故障)。 4. **集群升级/扩容风险** - 引用[2]证明:集群升级需记录槽位分布,无备份则无法恢复数据一致性。 --- ### 二、Redis Cluster备份方案 #### 1. **自动化RDB快照备份** ```bash # 每6小时备份一次,保存到异地存储 0 */6 * * * redis-cli -h <cluster-node> --rdb /backup/redis-$(date +\%s).rdb \ && aws s3 cp /backup/*.rdb s3://backup-bucket/ ``` - **优势**:兼容Cluster架构,文件小(压缩二进制) - **注意**:需轮询所有主节点备份(16384个槽需全覆盖) #### 2. **AOF持久化+日志同步** ```redis # redis.conf配置 appendonly yes appendfsync everysec # 平衡性能与安全 ``` - **操作**:用`rsync`实时同步AOF文件至异地服务器 - **恢复**:用`redis-check-aof`修复文件后加载 #### 3. **混合灾备架构** ```mermaid graph LR A[Redis Cluster] --> B(主节点RDB备份) A --> C(Slave节点AOF同步) B --> D[云存储(S3/OSS)] C --> E[异地日志服务器] D & E --> F[定期恢复验证] ``` --- ### 三、决策建议表 | **场景** | **备份策略** | 关键动作 | |--------------------------|----------------------------------|------------------------------------------| | 容忍分钟级数据丢失 | RDB快照 + 跨区域存储 | 每日验证备份文件可恢复性 | | 零数据丢失需求 | AOF实时同步 + RDB增量备份 | 部署日志审计追踪写入操作 | | 防御地域灾难 | 跨云厂商备份 + 只读副本集群 | 季度灾备演练 | | 大规模集群(TB级) | 分片备份 + 槽位元数据保存 | 记录`CLUSTER SLOTS`输出[^2] | > **关键结论**:Redis Cluster的分布式特性不替代备份!异步复制和持久化间隔仍存在数据丢失窗口,备份是最后防线。 --- ### 四、运维最佳实践 1. **验证备份有效性** ```bash # 恢复测试(需隔离环境) redis-server --port 6380 --dbfilename backup.rdb redis-cli -p 6380 CLUSTER ADDSLOTS {0..5500} # 按原槽位分配 ``` 2. **监控备份完整性** - 指标:`last_save_time`,`aof_current_size` - 告警规则:超过2小时无新备份则触发 3. **元数据保护** - 定期保存集群节点拓扑:`redis-cli -c CLUSTER NODES > cluster_topology.txt` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值