从the answer 到链接的问题,Carlo Bertuccini 写道:
保证一致性的是以下不等式
(WRITE CL + READ CL) > REPLICATION FACTOR
此问题中的情况 A、B 和 C 似乎是指满足该不等式的三种最小方式,如同一答案中给出的那样。
案例A
WRITE ALL 会将数据发送到all replicas。如果您的复制因子 (RF) 为三 (3),则 WRITE ALL 在向客户端报告成功写入之前写入三个副本。但是您不可能看到在下一次读取相同的数据键之前发生了写入。最低限度,READ ONE 将从上述单个副本中读取,并满足必要条件:WRITE(3) + READ(1) > RF(3)
案例 B
WRITE ONE 只会将数据发送到单个副本。在这种情况下,获得一致读取的唯一方法是从所有中读取。协调器节点将获得所有答案,找出哪个是最新的,然后向过期的副本发送“提示”,通知他们有一个更新的值。提示是异步发生的,但只有在READ ALL 发生后才满足必要条件:WRITE(1) + READ(3) > RF(3)
案例 C
QUORUM 操作必须涉及FLOOR(RF / 2) + 1 副本。在我们的 RF=3 示例中,即FLOOR(3 / 2) + 1 == 1 + 1 == 2。同样,一致性取决于读取和写入。在最简单的情况下,读操作与写操作使用的副本完全相同,但这不能保证。在一般情况下,执行读取操作的协调器节点将与 至少一个 写入使用的副本进行通信,因此它将看到更新的值。在这种情况下,就像READ ALL 的情况一样,协调节点将获得所有答案,找出哪个是最新的,然后向过期的副本发送“提示”。当然,这也满足必要条件:WRITE(2) + READ(2) > RF(3)
所以对于 OP 的问题...
是否可以“合并”案例 A 和 B?
为了确保一致性,只有在您的意思是WRITE ALL + READ ALL 时才可以“合并”,因为在上述情况下,您始终可以增加读取器或写入器的数量。
但是,如果您需要读取一致数据,WRITE ONE + READ ONE 并不是一个好主意,所以我的回答是:否。同样,使用该不等式和我们的示例 RF=3:WRITE(1) + READ(1) > RF(3) 不成立。如果您要使用此配置,则会收到 no value cannot betrusted 的答案 - 这仅表示已联系 one 副本做读取没有价值。但值可能存在于一个或多个其他副本上。
因此,从这个逻辑来看,在收到 no value 答案时执行READ ALL 似乎可以解决问题。它适用于该用例,但还有另一个需要考虑:如果您从 READ ALL 获得 一些价值...你怎么知道该价值返回的是“最新”的吗?这就是我们想要一致性时的意思。如果您关心阅读最近的写入,则需要满足不等式。
关于已编辑问题中“时间线”通知的用例
如果我对您描述的场景的理解是正确的,那么这些是您的用例的要点:
- 大多数(但不是全部?)时间线条目将一次性写入(以后不会修改)
- 可以关注任何此类条目(有关注者列表)
- 可以评论任何此类条目(有一个 cmets 列表)
- 对时间线条目的任何评论都应触发对该时间线条目的关注者列表的通知
- 尝试最小化“正常”情况下的成本(在这种情况下,以带宽衡量)
- 愿意依赖 Cassandra 内置的反熵功能(例如读取修复)
如果通知已发送给关注者,我需要确保用户可以收到评论。
由于您的大多数条目都是一次性写入的,并且您更关心条目的存在,而不一定是条目的最新内容,因此您也许可以使用@987654341 @ 回退到READ ALL,如果您没有得到有其他迹象表明它应该存在的东西的记录(例如来自通知)。对于时间线条目的内容,听起来并不像你的情况取决于时间线条目的用户内容的一致性。
如果你不关心一致性,那么这个讨论是没有意义的;以任何一致性级别读/写,并让 Cassandra 的异步复制和反熵功能完成它们的工作。也就是说,尽管您的目标是最小化网络流量/成本,但如果您的工作负载主要是读取,那么在 CL QUORUM 或 ALL 进行 写入 的额外成本可能实际上并没有那么多。
你也说过:
关注者收听帖子后会收到cmet加入帖子的通知。
此声明意味着您不仅关心关注者集 是否存在,还关心其内容(哪些用户正在关注) .您尚未详细说明如何存储/跟踪关注者,但除非您确保此数据的一致性,否则可能不会通知一个或多个关注者有新的评论,因为您检索到的关注者列表的过时版本。或者,“取消关注”帖子的人仍然可以出于同样的原因收到通知。
Cassandra 非常灵活,允许每个离散的读写操作使用不同的一致性级别。利用这一点,在需要的地方确保强一致性,在你确信“读取最新写入”对应用程序的逻辑和功能不重要的地方放宽它。