2

我知道在 Cassandra 中,除非您明确要求,否则没有强一致性(即使这样,也没有事务)。

但是,我对一致性的“顺序”感兴趣。举个例子:

在一个数据库节点中,有 3 个节点(A、B 和 C)。两个插入查询是通过相同的 CQL 连接发送的(或者就此而言,我认为这与这个问题无关)。两者都在不同的表上运行(这可能是相关的)。

INSERT INTO table_a (id) VALUES (0)
INSERT INTO table_b (id) VALUES (1)

在问题被发送到的节点上成功执行后,它立即关闭。该节点可能成功也可能未成功将这两个查询传播到 B 和 C。

现在,我认为有一个一致性的顺序。要么两者都在 B 和 C 上成功传播和执行,要么只有第一个查询是,或者两者都是。我认为,在任何情况下都不会传播和执行第二个查询,而不是第一个(因为 tcp 数据包的顺序,以及显然所有节点共享相同的一致性策略的事实)。

我对吗?

4

1 回答 1

4

你是对的,至少在你连接的节点上。服务器上发生的情况是,对于一致性级别 ONE 写入:

  1. 接收插入到 table_a
  2. 写入提交日志
  3. 确认写给客户端
  4. 接收插入到 table_b
  5. 写入提交日志
  6. 确认写给客户端

关键是有一个全局提交日志。所以你不能为一张桌子而不是另一张桌子冲洗它。此外,由于写入是连续的,因此您知道在返回之前已对提交日志进行了写入。

提交日志会定期刷新(默认情况下),因此可以在 2 之后但 5 之前刷新,在这种情况下,只有在 4 或 5 之后发生崩溃时才会保留对 table_a 的插入。

在其他节点上,不能保证顺序,因为写入是异步完成的,并且写入是多线程的。但是,如果原始节点没有永久失败,则不可能完全丢失第一次写入而不是第二次写入。

如果你想要更强的保证,你可以使用 Cassandra 的批处理。

如果您将它们作为批处理写入,Cassandra 可以保证两个写入都不会成功。即使对于旧的 Cassandra 版本,如果批处理中的更新具有相同的行键(CQL 中的分区键),即使它们位于不同的列族(表)中,它们也会自动提交到提交日志。

1.2 中的新功能是跨多行的批处理日志,它提供相同的保证——要么应用所有批处理,要么不应用任何批处理。

于 2013-08-17T08:37:12.867 回答