redis 脑裂等极端状况分析

脑裂真的是一个很头疼的问题(ps: 脑壳都裂开了,能不疼吗?),看下面的图:html

1、哨兵(sentinel)模式下的脑裂redis

 

 

如上图,1个master与3个slave组成的哨兵模式(哨兵独立部署于其它机器),刚开始时,2个应用服务器server一、server2都链接在master上,若是master与slave及哨兵之间的网络发生故障,可是哨兵与slave之间通信正常,这时3个slave其中1个通过哨兵投票后,提高为新master,若是刚好此时server1仍然链接的是旧的master,而server2链接到了新的master上。数据库

数据就不一致了,基于setNX指令的分布式锁,可能会拿到相同的锁;基于incr生成的全局惟一id,也可能出现重复。服务器

2、集群(cluster)模式下的脑裂网络

 

 

custer模式下,这种状况要更复杂,见上面的示意图,集群中有6组分片,每给分片节点都有1主1从,若是出现网络分区时,各类节点之间的分区组合都有可能,上面列了2种状况:分布式

状况A:3d

假设master1与slave4落到同1个分区,这时slave4通过选举后,可能会被提高为新的master4,而另外一个分区里的slave1,可能会提高为新的master1。看过本博客前面介绍redis cluster的同窗应该知道,cluster中key的定位是依赖slot(槽位),状况A通过这一翻折腾后,master1与master4上的slot,出现了重复,在二个分区里都有。相似的,若是依赖incr及setNX的应用场景,都会出现数据不一致的状况。server

状况B:htm

若是每给分片内部的逻辑(即:主从关系)没有乱,只是刚好分红二半,这时slot总体上看并无出现重复,若是原来请求的key落在其它区,最多只是访问不到,还不致于发生数据不一致的状况。(即:宁肯出错,也不要出现数据混乱)blog

3、主从迁移带来的不一致

 

 

如上图,1主1从,若是采用incr来生成全局惟一键,假如master上的值是4,可是还没有同步到slave上(slave上仍然是旧值3),这时候若是发生选举,slave被提高为新master,应用服务器server1切换到新主后,下次再incr获取的值,就可能重复了(3+1=4)

总结:虽然上面的状况都比较极端,但实际中仍是有可能发生的,正如官方文档所言,redis并不能保证强一致性(Redis Cluster is not able to guarantee strong consistency. / In general Redis + Sentinel as a whole are a an eventually consistent system) 对于要求强一致性的应用,更应该倾向于相信RDBMS(传统关系型数据库)。

参考:

http://www.redis.io/topics/sentinel

https://redis.io/topics/cluster-tutorial

相关文章
相关标签/搜索