当节点在事务之间死亡/脱机时出现 Cassandra 一致性问题



我有一个场景

假设我们在集群中有 6 个节点,复制因子为 3。 现在我们使用仲裁写入,所以假设协调器看到 3 个节点在数据需要去的地方,但当它将数据发送到 3 个节点 n1、n2、n3 时。N1 和 N2 停止工作,因此写入操作将失败,因为未满足仲裁,但 N3 将具有此失败的更新插入的数据,因为 Cassandra 没有回滚。

在此之后,n1 和 n2 出现,但数据较旧。

现在,如果读取完成,在读取修复中,n3上存在的最新数据(失败的更新器(将被复制到n1和n2,我的理解是否正确?

是的,你是对的。

如果对该记录运行读取修复,则将从 n3 复制数据。这将取决于您对read_repair_chance的配置以及查询记录的频率。

如果记录未被大量查询,则不太可能运行读取修复,并且必须等待修复运行。

如果您不定期运行nodetool repair,您应该开始这样做!

请注意,如果在修复发生之前以QOURUM一致性读取,则仍将获得旧值。

有两种不同类型的错误。如果 n1 和 n2 为 DOWN,则写入甚至不会转到 n3,并且您将获得不可用异常且没有问题。

如果 n1 和 n2 在写入开始后关闭或有一些灾难性的损失,那么数据仍将存在于 n3 上,您将获得一个 WriteTimeoutException,因为 n3 协调器将坐下来等待其他 2 个副本响应。在写入超时时,您需要以不同的方式处理错误,通常是使用串行读取(如果使用 LWT(或其他读取方式进行检查。通常,尽管写入是幂等的,您可以重试。

使用 QUORUM 和 rf=3,您只能真正安全地处理一个节点出现故障。一旦你得到 2 个副本,你就会遇到很多潜在的问题,甚至数据丢失。这就是为什么如果数据真的很重要,许多人会使用多个 DC 和更高的复制因子,这样丢失 DC 甚至不会影响事情。

最新更新