设为首页 收藏本站
查看: 633|回复: 0

[经验分享] Redis Cluster的FailOver失败案例分析

[复制链接]

尚未签到

发表于 2016-12-20 08:27:56 | 显示全部楼层 |阅读模式
场景:
      使用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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-316665-1-1.html 上篇帖子: redis安装使用-进阶篇(持久化) 下篇帖子: Redis、Memcached、Guava、Ehcache中的算法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表