【问题标题】:What are the common practice to handle Cassandra write failure?处理 Cassandra 写入失败的常见做法是什么?
【发布时间】:2013-04-15 14:58:21
【问题描述】:
在文档 [1] 中,据说
if using a write consistency level of QUORUM with a replication factor
of 3, Cassandra will send the write to 2 replicas. If the write fails on
one of the replicas but succeeds on the other, Cassandra will report a
write failure to the client.
所以假设只有 2 个副本收到更新,写入失败。但由于最终一致性,所有节点最终都会收到更新。
那么,我应该重试吗?还是保持原样?
有什么策略吗?
[1]http://www.datastax.com/docs/1.0/dml/about_writes
【问题讨论】:
标签:
database
cassandra
consistency
eventual-consistency
【解决方案1】:
那些文档并不完全正确。无论一致性级别(CL)如何,写入都会发送到所有可用的副本。如果副本不可用,Cassandra 不会向宕机节点发送请求。如果从一开始就没有足够的可用资源来满足 CL,则会抛出 UnavailableException 并且不会尝试写入任何节点。
但是,在某些节点上写入仍然可以成功,并向客户端返回错误。在 [1] 的示例中,如果在尝试写入之前有一个副本已关闭,则写入的内容为 true。
所以假设只有 2 个副本收到更新,写入失败。但
由于最终一致性,所有节点都会收到更新
最后。
但要小心:写入失败不会告诉您写入了多少个节点。可能没有,所以写入最终可能不会传播。
那么,我应该重试吗?还是保持原样?
一般来说你应该重试,因为它可能根本没有写。只有当您从 write 中成功返回时,您才应该将您的 write 视为已写入。
如果您使用计数器,但您应该小心重试。因为您不知道是否进行了写入,所以您可能会得到重复计数。对于计数器,您可能不想重试(因为大多数情况下,至少会写入一个节点,至少对于更高的一致性级别而言)。
【解决方案2】:
重试不会有太大变化。问题是您实际上根本不知道数据是否被持久化,因为 Cassandra 总是抛出相同的异常。
你有几个选择:
- 启用提示并使用 cl=any 重试请求 - 成功响应意味着至少创建了提示。所以你知道数据在那里但还不能访问。
- 禁用提示并重试一次 - 成功响应意味着至少节点可以接收数据。如果出错执行删除。
- 使用 astyanax 及其重试策略
- 更新到 Cassandra 1.2 并使用预写日志