`
xiaoZ5919
  • 浏览: 399554 次
  • 性别: Icon_minigender_1
  • 来自: 安平人@北京
博客专栏
Group-logo
Netty学习笔记
浏览量:72678
社区版块
存档分类
最新评论

Redis Cluster的FailOver失败案例分析

阅读更多
场景:
      使用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很费神,大家看起也会很费解。感谢有道词典
1
0
分享到:
评论
2 楼 sunnyhappylg 2017-11-01  
问题:一个已经在线的redis集群 如何进行升级,需要把整个集群停掉 做升级 再重启?对于有几百个节点redis集群该怎么做呢
1 楼 carlosfu 2015-03-06  
写的很好,如果有配图就更好了。

相关推荐

    Redis偶发连接失败案例分析.rar

    Redis偶发连接失败案例分析.rar

    Redis高可用集群Redis Cluster搭建

    Redis高可用集群Redis Cluster搭建

    codis/redis 迁移redis cluster工具

    支持codis迁移数据到redis 支持codis迁移数据到redis cluster 支持redis迁移数据到redis 支持redis迁移数据到codis 支持增量同步数据

    RedisCluster集群(Spring访问Redis)

    RedisCluster集群(Spring访问Redis),初学者实例源码

    Redis Cluster的实现机制和原理

    Redis Cluster主要特性和设计,Redis Cluster主要特性和设计

    Redis cluster最佳实践

    我在做redis cluster的时候发现,两节点的cluster在处理断网或单节点故障时,会出现脑裂情况,为此,我做了实验去测试redis cluster配置的最佳方式,本文包含了测试的全过程。

    RedisCluster.zip

    RedisCluster 集群搭建文件RedisCluster 集群搭建文件RedisCluster 集群搭建文件

    redisCluster集群demo

    redisCluster集群demo,java语言用于获取Redis集群的数据连接池并获取数据。

    redis cluster配置文件

    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 spring整合代码

    个人测试redis cluster spring整合代码 的demo

    Windows下安装部署redis cluster

    Windows下安装部署redis cluster,亲测好使,包含 安装环境,redis-3.2.1.gem,redis cluster集群实例

    redisCluster.zip

    redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/...

    rediscluster.rar

    集群版redis,使用MySQL数据库,里面有批处理的SQL,性能十分卓越,单机版经供参考,抛转引玉,doc中包含数据库文件

    rediscluster配置文件.zip

    6389为6379的从节点,6390为6380的从节点,6391为6381的从节点。三主三从,下载完了修改bind dir masterauth cluster

    Redis官方Cluster搭建配置步骤详解

    Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。 Redis集群并 不支持处理多个keys... 本文,是我自己写的Redis Cluster集群搭建和配置详细步骤,包含了常用的Redis配置文件,和节点的管理等,以供大家参考.

    Redis Cluster部署文档.docx

    redis3.0版本cluster安装部署配置和管理,样例演示, 集群操作常用命令 CLUSTER INFO 打印集群的信息 CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。

    redis-trib.rb是官方提供的Redis Cluster的管理工具

    redis-trib.rb是官方提供的Redis Cluster的管理工具,无需额外下载,默认位于源码包的src目录下,但因该工具是用ruby开发的,所以需要准备相关的依赖环境。

    Tomcat 8+ redis cluster session

    在不改变工程代码的情况下,使tomcat多个节点利用redis cluster进行session共享.

    Redis Cluster集群部署搭建详解附件

    Redis Cluster集群部署搭建详解附件,转自linux公社,里面有redis搭建集群的例子。供大家参考

Global site tag (gtag.js) - Google Analytics