Redis Cluster无法保证强一致性。实际上,这意味着在某些条件下,Redis Cluster可能会丢失系统向客户端确认的写入。

Redis Cluster可能丢失写入的第一个原因是它使用异步复制。这意味着在写入期间会发生以下情况:

  • 您的客户端写入主B.
  • 主人B向您的客户回复确定。
  • 主设备B将写入传播到其从设备B1,B2和B3。

正如你所看到的,B在回复客户端之前并没有等待来自B1,B2,B3的确认,因为这对Redis来说是一个过高的延迟惩罚,所以如果你的客户端写了一些内容,B会确认写入,但是在崩溃之前崩溃能够将写入发送到其从属,其中一个从属(没有接收到写入)可以被提升为主,永远丢失写入。

这与配置为每秒将数据刷新到磁盘的大多数数据库所发生的情况非常相似,因此,由于过去使用不涉及分布式系统的传统数据库系统的经验,因此您已经能够推断这种情况。同样,您可以通过在回复客户端之前强制数据库刷新磁盘上的数据来提高一致性,但这通常会导致性能过低。在Redis Cluster的情况下,这相当于同步复制。

基本上需要在性能和一致性之间进行权衡。

Redis Cluster在绝对需要时支持同步写入,通过WAIT命令实现,这使得丢失写入的可能性大大降低,但请注意,即使使用同步复制,Redis Cluster也不会实现强一致性:在更复杂的情况下总是可以实现失败场景,无法接收写入的从站被选为主站。

还有另一个值得注意的情况是,Redis群集将丢失写入,这种情况发生在网络分区中,其中客户端与少数实例(至少包括主服务器)隔离。

以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的一个非常重要的配置指令,称为节点超时

节点超时过后,主节点被视为失败,可以由其中一个副本替换。类似地,在节点超时已经过去而主节点无法感知大多数其他主节点之后,它进入错误状态并停止接受写入。