将数据写入Cassandra中的副本但协调器由于缺少仲裁而将超时异常返回给客户端时会发生什么情况?

问题描述

场景:

  1. 客户端向协调器节点发送写请求
  2. 复制因子为3,读/写一致性级别为QUORUM。
  3. 协调器将请求发送到节点A,B和C。数据已提交给节点A,但是节点B和C在从协调器接收到请求后立即关闭。 协调器将向客户端发送超时异常,因为它未在分配的时间内收到来自节点B和C的确认。现在,节点A上的数据与节点B和C上的数据不一致。 根据我的理解,在读取修复期间,将使用节点A上的值更新节点B和C。因此我们这里有一个超时异常,但新值最终已写入所有节点。

还有其他新的数据尚未写入任何节点的超时异常。

因此,看来开发人员应该在代码中处理超时异常,这在所有情况下可能都不是直截了当的(因为新值可能在某些情况下而不是在其他情况下写入,因此开发人员必须检查该情况)在超时后重试期间)。

我正在学习Cassandra。因此,如果我的理解不正确,请纠正我。

你们中有些人可能会说这也发生在关系数据库中,但是由于它不是分布式系统,因此在这种情况下很少发生。

这里有一些我发现的文章,但并未具体解决我的问题。

What happens if a coordinator node goes down during a write in Apache Cassandra?

https://www.datastax.com/blog/2012/08/when-timeout-not-failure-how-cassandra-delivers-high-availability-part-1

解决方法

如果写入了数据,则表明数据是一致的,即使节点B和C没有发送ACKT: 当节点接收到数据时,它将首先进入提交日志,如果节点崩溃,则它将在重新启动后立即重播变异。

如第二篇文章所述,它更像是InProgressException,而不是TimedOutException。

在客户端,如果您有TimedOutException,则不能100%确定是否已写入数据,但是可以。

对于您的情况,如果节点B和C接收到写操作,即使它们未发送ACK,数据也是一致的。即使只有两个节点之一,由于使用QUORUM,数据也是一致的。

集群方面,有多种机制可以使Cassandra更加一致:提示切换,读取修复和修复。

为了更好地理解,也许值得一看:

写入路径:

https://docs.datastax.com/en/cassandra-oss/2.1/cassandra/dml/dml_write_path_c.html

提示切换:

https://docs.datastax.com/en/cassandra-oss/2.1/cassandra/dml/dml_about_hh_c.html

阅读维修:

https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/operations/opsRepairNodesReadRepair.html

,

感谢您的回复。从最终用户/开发人员的角度来看,它仍然无济于事,因为我需要编写代码来处理异常。

无论价值多少,我都在DataStax上找到了以下文章。 https://www.datastax.com/blog/2014/10/cassandra-error-handling-done-right

如果您参考以下部分 “ WriteTimeOutException”和“非幂等操作”,您可以看到 最终用户应在收到异常后重试。 如果是幂等操作,则在应用程序端不需要其他代码。对于非等幂运算,事情并非那么简单。 Cassandra假定大多数写操作通常都是幂等的,我不一定同意这一点。业务规则取决于应用程序。

非幂等运算的示例: 更新表设置计数器=计数器+ 1,其中键='xyz' 或更新表设置的佣金=佣金* 1.02,其中键='abc'

本文在“非等幂运算”部分中提供了一些有关如何使用CAS /轻量级事务处理非等幂运算的建议。这会使客户端代码变得复杂/丑陋,尤其是当代码中包含大量DML时。

即使这不是我要找的答案,但看来至少目前没有更好的方法。