redis 脑裂等极端情况分析
ddatsh
哨兵(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