脚本:
客户端向协调器节点发送写请求
复制因子为3,读/写一致性级别为quorum。
协调器将请求发送到节点a、b和c。数据被提交到节点a,但是节点b和c在接收到来自协调器的请求后立即停机。协调器将向客户端发送超时异常,因为它在分配的时间内没有从节点b和c接收到ack。现在节点a上的数据与节点b和c上的数据不一致。根据我的理解,在读修复期间,节点b和c将用节点a上的值更新。所以我们这里有一个超时异常,但是新值最终被写入所有节点。
在新数据尚未写入任何节点的情况下,可能存在其他超时异常。
因此,似乎期望开发人员在代码中处理超时异常,这在所有情况下可能都不简单(因为新值可能在某些情况下写入,而在其他情况下则不写入,并且开发人员必须在超时后的重试过程中检查该异常)。
我只是在学Cassandra。所以如果我的理解不正确,请纠正我。
有些人可能会说这种情况也发生在关系数据库中,但这种情况很少发生,因为它不是分布式系统。
这里有一些文章,我发现,但它没有解决我的问题具体。
如果协调器节点在apache cassandra中写入时发生故障,会发生什么情况?
https://www.datastax.com/blog/2012/08/when-timeout-not-failure-how-cassandra-delivers-high-availability-part-1
2条答案
按热度按时间ars1skjm1#
谢谢你的回复。从最终用户/开发人员的Angular 来看,这仍然无助于回答这个问题,因为我需要编写代码来处理异常。
不管值多少钱,我找到了下面这篇关于税收的文章。https://www.datastax.com/blog/2014/10/cassandra-error-handling-done-right
如果您参考“writetimeoutexception”和“non-idempotent operations”部分,您可以看到最终用户在收到异常后将进行重试。如果它是一个幂等运算,那么在应用程序端就不需要额外的代码。对于非幂等运算,事情并不是那么简单。cassandra假设大多数写操作通常是幂等的,我不一定同意这一点。业务规则取决于应用程序。
非幂等运算示例:update table set counter=counter+1,其中key='xyz'或update table set commission=commission*1.02,其中key=''
本文在“非幂等操作”部分给出了一些关于如何使用cas/轻量级事务处理非幂等操作的建议。这使得客户机代码变得复杂/难看,尤其是当代码中有大量dml时。
尽管这不是我想要的答案,但至少目前看来没有更好的办法了。
uhry853o2#
如果向您写入数据,那么它是一致的,即使节点b和c没有发送ackt:当节点接收到数据时,它首先进入提交日志,如果节点崩溃,那么它将在再次启动时重播该变异。
正如第二篇文章所说,它更像inprogressexception,而不是timedoutexception。
在客户端,如果您有timedoutexception,您不能100%确定数据是否已写入,但它可能已写入。
对于您的情况,如果节点b和c接收到的写操作,即使它们没有发送ack,数据也是一致的。即使两个节点中只有一个这样做了,由于仲裁的使用,数据也是一致的。
在集群方面,有几种机制可以让hep-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