redis 脑裂等极端情况分析

ddatsh

db #redis redis

哨兵(sentinel)模式下的脑裂

1 master、3 slave、哨兵独立部署

最初,2个应用服务器server1、server2都连接在master上

master与slave及哨兵之间的网络发生故障,但哨兵与slave通讯正常,这时3个slave其中1个经过哨兵投票后,提升为新master

如果server1仍连的旧master,而server2连到了新master上

数据就不一致了,基于setNX指令的分布式锁,可能会拿到相同的锁

基于incr生成的全局唯一id,也可能出现重复

集群(cluster)模式下的脑裂

custer模式下,情况要更复杂

集群有6组分片,每个分片节点都有1主1从

出现网络分区时,各种节点之间的分区组合都有可能

情况A:

master1与slave4落到同1个分区,slave4经选举后可能会被提升为新的master4,而另一个分区里的slave1,可能会提升为新的master1

cluster中key的定位依赖slot,情况A经过这一翻折腾后,master1与master4上的slot,出现了重复,在二个分区里都有

类似,依赖incr及setNX的场景,都会出现数据不一致的情况

情况B:

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

主从迁移带来的不一致

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