- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
您能否解释一下为什么即使使用基于法定人数的读写,Cassandra 也不能线性化?
线性度定义为
If operation B started after operation A successfully completed, then operation B must see the system in the same state as it was on completion of operation A, or a newer state.
最佳答案
编辑考虑 Cassandra 前景读取修复:
由于仅更新了部分副本集而导致的写入失败可能会导致两个不同的读者看到两个不同的数据值。这是因为在简单的基于群体的一致性方法中缺少回滚。此行为破坏了单键读取的线性化保证。如本 discussion 中所述,Raft 或 Paxos 等分布式共识协议(protocol)是此类保证的必备条件。
还有其他现象,例如 clock drift和 leap second可以破坏 Cassandra session 的一致性。
较早的回答(不考虑 Cassandra 前台读取修复):
总结:在 Cassandra 中,写可能感觉不到原子性。有些节点的写入速度比其他节点快,因此即使我们依赖仲裁,结果也取决于返回值的节点集以及它们在该点持有的值。
此外,为了解释添加到粗体定义中的线性化的定义
If operation B started after operation A successfully completed, thenoperation B must see the system in the same state as it was oncompletion of operation A, or a newer state (but never old state again) .
从 Martin Klepmann 的数据密集型应用程序一书中复制
线性化和群体直觉上,似乎严格的法定人数读写在 Dynamo 风格的模型中应该是可线性化的。然而,当我们有可变的网络延迟时,可能会出现竞争条件,如图 9-6 所示。
在图 9-6 中,x 的初始值为 0,写入客户端通过将写入发送到所有三个副本(n = 3,w = 3)来将 x 更新为 1。同时,客户端 A 从两个节点 (r = 2) 的法定人数中读取并在其中一个节点上看到新值 1。同样在写入的同时,客户端 B 从两个节点的不同仲裁中读取,并从两个节点取回旧值 0。
满足法定人数条件 (w + r > n),但此执行仍然不可线性化:B 的请求在 A 的请求完成后开始,但 B 返回旧值,而 A 返回新值。 (这又是图 9-1 中爱丽丝和鲍勃的情况。)
有趣的是,有可能以降低性能为代价使 Dynamo 样式的仲裁可线性化:读取器必须同步执行读取修复(请参阅第 178 页的“读取修复和反熵”),然后再将结果返回给应用程序 [23 ],并且写入者必须在发送其写入之前读取法定数量的节点的最新状态 [24、25]。然而,由于性能损失 [26],Riak 不执行同步读取修复。 Cassandra 确实会等待读取修复完成仲裁读取 [27],但如果对同一键有多个并发写入,它会失去线性一致性,因为它使用了最后写入获胜的冲突解决方案。
而且,这种方式只能实现可线性化的读写操作;可线性化的比较和设置操作不能,因为它需要共识算法 [28]。
总而言之,最安全的假设是具有 Dynamo 式复制的无领导者系统不提供线性化。
关于线性化与序列化的更多解释:
关于database - 为什么在使用基于法定人数的读写时 Cassandra 不可线性化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56795239/
我是一名优秀的程序员,十分优秀!