我知道在Cassandra中,没有强烈的一致性,除非你明确要求它(即便如此,也没有交易) .
但是,我对一致性的“顺序”感兴趣 . 请看以下示例:
在数据库节点中,有3个节点(A,B和C) . 通过相同的CQL连接发送两个插入查询(或者就此问题而言,我也不会发送与此问题相关的问题) . 两者都在不同的表上运行(这可能是相关的) .
INSERT INTO table_a (id) VALUES (0)
INSERT INTO table_b (id) VALUES (1)
在问题已成功执行到它们被发送到的节点上之后,它会立即关闭 . 节点可能已成功或未成功将这两个查询传播到B和C.
现在,我认为,在任何情况下,只有第二个查询被传播和执行,而不是第一个(因为tcp数据包的顺序,显然,所有节点都共享相同的一致性策略) .
我对吗?
1 回答
你是对的,至少在你连接的节点上 . 在服务器上发生的事情是,对于一致性级别ONE写:
接收插入到table_a
写入commitlog
确认写给客户
接收对table_b的插入
写入commitlog
确认写给客户
关键是有一个全局的提交日志 . 所以你不能为一张 table 而不是另一张 table 冲洗它 . 此外,由于写入是顺序的,因此您知道在返回之前已对commitlog进行了写入 .
commitlog定期刷新(默认情况下),因此可以在2之后但在5之前刷新,在这种情况下,只有在4或5之后立即发生崩溃时才会保留对table_a的插入 .
在其他节点上,无法保证排序,因为写入是异步完成的,并且写入是多线程的 . 但是如果原始节点没有永久失败,则不可能完全丢失第一次写入而不是第二次写入 .
如果你想要更强的保证,你可以使用Cassandra的批处理 .
如果您将它们作为批处理写入,Cassandra可以保证写入中的任何一个或两个都不会成功 . 对于旧的Cassandra版本,如果批处理中的更新具有相同的行键(CQL中的分区键说话),即使它们位于不同的列族(表)中,它们也会以原子方式提交到commitlog .
1.2中的新增内容是跨多行的批处理日志,提供相同的保证 - 要么应用所有批处理,要么不应用 .