首先需要明确的是,Redis是不能保证强一致性的。原因有以下两点:
(1)Redis集群是异步复制,为了保证性能,客户端请求写入master后,master先回复客户端,然后才将写操作复制给slave。同步期间如果master宕机,slave升为主的期间就会丢失部分数据。
(2)Redis集群可能出现网络分区,这种情况下,一个客户端和至少一个主节点A在内的少数示例所在的分区会被孤立。因为客户端可以继续写入A,但是其他分区由于无法与这个分区通信,就会选举slave A1升为master,那么A被写入的数据就会丢失。具体如下(参考博客 https://blog.csdn.net/CurryClot/article/details/88574342):
以6个节点簇为例,包括A,B,C,A1,B1,C1,3个主站和3个从站。还有一个客户,我们称之为Z1。
在发生分区之后,可能在分区的一侧有A,C,A1,B1,C1,在另一侧有B和Z1。
Z1仍然可以写入B,它将接受其写入。如果分区在很短的时间内恢复,群集将继续正常运行。但是,如果分区持续足够的时间使B1在分区的多数侧被提升为主,则Z1发送给B的写入将丢失。
请注意,Z1将能够发送到B的写入量存在最大窗口:如果分区的多数方面已经有足够的时间将从属设备选为主设备,则少数端的每个主节点都会停止接受写入。
这段时间是Redis Cluster的一个非常重要的配置指令,称为节点超时。
节点超时过后,主节点被视为失败,可以由其中一个副本替换。类似地,在节点超时已经过去而主节点无法感知大多数其他主节点之后,它进入错误状态并停止接受写入。