Redis Cluster的FailOver失败案例分析

标签: redis cluster failover | 发表时间:2015-02-05 17:51 | 作者:
出处:http://www.iteye.com
场景:
      使用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很费神,大家看起也会很费解。感谢有道词典

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [redis cluster failover] 推荐:

Redis Cluster的FailOver失败案例分析

- - ITeye博客
      使用redis clusterRC1部署集群,6台机器,每台部署16个实例,每个master使用一个slave,node_timeout为默认值(15s). kill掉其中一个master发现failover完成不了. 通过cluster nodes观察,该节点一直处于pfail状态. 问题出在失败判定上,一直处于PFail,说明完成不了PFail->Fail的转换.

在 Percona XtraDB Cluster 裡使用 async replication 時人工 failover 的方式…

- - Gea-Suan Lin's BLOG
在使用 Galera Cluster 時還是可以架設一般的 slave server ( Percona XtraDB Cluster 則是 Percona 對 Galera Cluster 的封裝),像是這樣的架構:. 其中 node{1,2} 為 cluster,node3 則是傳統的 async replication,來源的 master 為 node1.

Redis Cluster理论整理

- - 开源软件 - ITeye博客
Redis 集群的 TCP 端口(Redis Cluster TCP ports). 每个 Redis 集群节点需要两个 TCP 连接打开. 正常的 TCP 端口用来服务客户端,例如 6379,加 10000 的端口用作数据端口,在上面的例子中就是 16379. 第二个大一些的端口用于集群总线(bus),也就是使用二进制协议的点到点通信通道.

Redis Cluster(Redis 3.X)设计要点

- - CSDN博客架构设计推荐文章
Redis 3.0.0 RC1版本10.9号发布, Release Note. 这个版本支持 Redis Cluster,相信很多同学期待已久,不过这个版本只是RC版本,要应用到生产环境,还得等等. Redis Cluster设计要点:. Redis Cluster采用无中心结构,每个节点都保存数据和整个集群的状态.

redis cluster百万QPS的挑战

- - 开源软件 - ITeye博客
最近在做redis cluster性能测试过程中,发现当集群吞吐量到达一定程度后(4台12core的redis服务器,80wQPS左右),集群整体性能不能线性增长. 也就是说,通过加机器不能提升集群的整体吞吐. 以下是详细记录了一下这个case的排查并最终解决的过程. 上图中每一条线代表一个起压端进程的压测QPS(一台起压机上开4个起压端),可以看到随着起压机的增多,每个起压机的QPS却在下滑.

Redis cluster tutorial Redis集群教程 官方教程 翻译 (一)

- - 互联网 - ITeye博客
这篇文档是一个总体介绍, 不使用复杂的分布式概念. 本文介绍如何建立一个集群, 测试和使用, 详细说明请参看 Redis Cluster specification. 注意, 如果你打算实际使用Redis集群, 推荐看正式的规范文档. Redis集群现在还在alpha测试, 请加入Redis邮件列表, 或Github repository的讨论组.

南航移动Redis-Cluster趟坑记 - 推酷

- -
当今IT界正处于移动互联浪潮中,涌现出一批批优秀的门户网站和电商平台. 在巨大的利润驱动下,这些公司都全力打造各自的系统以适应互联网市场发展的需要,而且在此过程中各个系统还不停地接受着亿万网民的检验. 经历过千锤百炼后,那些“名门大厂”都纷纷总结出“高可用,高可靠,高并发下低延迟”的优秀实践. 而南航电商营销平台这种带有国企背景和传统行业特色的电商系统在这股浪潮的引领之下,也逐步向这些“大厂”学习,结合自身的实际情况,在“高可用,高可靠,高并发下低延迟”的系统优化之路上展开一番游历探索,期间也游览了不少大坑暗沟.

Redis cluster集群模式的原理 - __Meng - 博客园

- -
  redis cluster是Redis的分布式解决方案,在3.0版本推出后有效地解决了redis分布式方面的需求.   自动将数据进行分片,每个master上放一部分数据.   提供内置的高可用支持,部分master不可用时,还是可以继续工作的.   支撑N个redis master node,每个master node都可以挂载多个slave node.

failover机制

- - 行业应用 - ITeye博客
通俗地说,即当A无法为客户服务时,系统能够自动地切换,使B能够及时地顶上继续为客户提供服务,且客户感觉不到这个为他提供服务的对象已经更换. 这里的A和B可以存在于各种领域,但一般fail-over特指计算机领域的数据库、应用服务、硬件设备等的失效转移. 【电脑】失效备援 (为系统备援能力的一种, 当系统中其中一项设备失效而无法运作时, 另一项设备即可自动接手原失效系统所执行的工作).

动手实践Redis主从复制、Sentinel主从切换、Cluster分片

- - 掘金 后端
Redis 提供的如下技术「Redis Sentinel『主从切换』、Redis Cluster『分片』」,有效实现了 Redis 的高可用、高性能、高可伸缩性,本文对以上技术进行亲自动手实践. Redis Sentinel「主从切换」. 监控主从节点的在线状态,并根据配置自行完成切换「基于raft协议」.