场景:
使用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吧。
对该文有任何问题,欢迎在微博上@小城大雷互相交流
------------------------------------
E文很烂,提issue很费神,大家看起也会很费解。感谢有道词典
分享到:
相关推荐
**RedisCluster集群与Spring访问Redis详解** Redis是一个高性能的键值数据库,广泛应用于缓存、消息中间件等场景。在大型分布式系统中,为了提供高可用性和数据冗余,我们通常会采用Redis Cluster来构建集群。本文...
Redis Cluster是Redis官方提供的分布式解决方案,它允许用户在多个节点之间分发数据,从而实现高可用性和水平扩展。本文将详细介绍Redis Cluster的工作原理、配置、使用以及与MySQL数据库的配合。 **一、Redis ...
在`redisCluster-demo`这个项目中,你可以期待找到一个使用Java实现的示例,展示如何配置和使用`JedisCluster`或者`Lettuce`来连接Redis Cluster,以及如何进行基本的数据操作。这个示例可以帮助初学者理解如何在...
Redis偶发连接失败案例分析.rar
这个压缩包文件"rediscluster配置文件.zip"包含了一系列配置文件,用于搭建一个三主三从的Redis Cluster架构。在这个架构中,每个主节点都有一个对应的从节点,确保在主节点失效时可以从其从节点接管服务,从而保持...
Redis高可用集群Redis Cluster搭建 Redis高可用集群Redis Cluster搭建是 Redis 官方推荐的高可用性解决方案,于 3.0 版本推出。Redis Cluster 的主要用途是实现数据分片(Data Sharding),同时也可以实现高可用...
使用JFinal Redis Cluster插件时,首先需要将其引入到项目中,这里我们看到有一个名为 "jfinal-rediscluster-plugin-by-shixiaotian-0.0.1.jar" 的文件,这应该是该插件的可执行版本。通常,开发者会将这个JAR文件...
**Redis Cluster简介** Redis Cluster是Redis的分布式解决方案,它提供了数据分片、故障转移和高可用性等功能。在大型系统中,单个Redis实例可能无法满足存储和性能需求,这时就需要利用Redis Cluster来扩展和分散...
Redis Cluster是Redis官方提供的分布式集群解决方案,它允许用户在多台服务器上部署Redis实例,形成一个高可用、可扩展的数据存储集群。Redis Cluster通过数据分片(Sharding)和槽分区(Slot Partitioning)策略来...
### Redis Cluster 的实现机制与原理 #### 集群的核心目标与特性 Redis Cluster 是 Redis 数据库的一个分布式版本,旨在解决单个 Redis 实例在处理大量数据和高并发请求时的局限性。其核心目标包括: 1. **高性能...
实验结果表明,在高并发访问数(例如10000以上)的场景下,RedisCluster的响应时间明显优于Codis系统,验证了RedisCluster分布式缓存系统在处理高并发访问时的高效率和优越性能。 关键词“分布式缓存”指的是分布式...
Redis Cluster是Redis官方提供的分布式解决方案,它通过将数据分片(sharding)到多个节点来实现高可用性和可扩展性。在本实战栗子中,我们将深入探讨如何搭建Redis Cluster,学习其基本概念、操作指令以及如何处理...
RedisCluster是Redis的一种分布式集群解决方案,它允许将数据分散存储在多个节点上,以实现高可用性和可扩展性。在RedisCluster中,每个节点都存储一部分数据,并且负责处理一部分客户端请求,这样可以分摊服务器...
【标题】:“Tomcat 8+ Redis Cluster Session” 在现代Web应用开发中,session管理是不可或缺的一部分,尤其是在分布式系统中。传统的session管理方式在多台服务器之间存在数据同步问题,导致用户状态无法共享,...
redis cluster配置文件,配置后的参考; 创建目录: mkdir -p /etc/redis-cluster mkdir -p /var/log/redis mkdir -p /var/redis/7001 mkdir -p /var/redis/7002 拷贝配置文件: cp /usr/local/redis-3.2.8/redis....
**Redis Cluster 搭建全攻略** Redis 是一个高性能的键值存储系统,而 Redis Cluster 是它的分布式解决方案,提供数据的自动分片、故障转移和高可用性。本指南将详细讲解如何完整地搭建一个 Redis Cluster,同时...
Redis Cluster 集群模式部署 本文将详细介绍 Redis Cluster 集群模式部署的步骤和配置过程。Redis Cluster 是 Redis 的一个高可用解决方案,通过将多个 Redis 节点组合成集群,提高 Redis 的可用性和性能。 环境...
Codis到Redis Cluster的迁移工具支持将已经在Codis集群中的数据平滑迁移到Redis Cluster,无需停机,保证业务的连续性。同样,它也支持从Redis迁移到Codis,以及在Redis实例之间进行迁移,这些功能使得数据管理更具...
Redis-Cluster是Redis的一个分布式实现,它允许在多个节点之间分散数据,提供高可用性和可扩展性。在Windows环境中配置Redis-Cluster,首先需要理解其基本概念和工作原理,然后按照步骤进行安装和配置。 一、Redis-...