免责声明:下面的文字应该让您大致了解最终一致性、强最终一致性和强一致性之间的区别。但它们在某种程度上过于简单化了。所以对它们持保留态度;)
首先,当我们谈论一致性我们指的是不同实体(节点)拥有自己的某些数据对象副本的场景。现在,出现冲突是因为每个节点都可以更新自己的副本(例如,因为有客户端,每个节点都连接到某个节点,要求它们这样做),所以如果我从不同的节点读取数据,我会看到不同的值。这就是最终一致性(EC)、强最终一致性(SEC)和强一致性(SC)发挥作用的地方。
最终一致性可能会出现冲突,但节点会相互传达其更改以解决这些冲突,因此它们会及时就最终值达成一致。因此,如果在一段时间内不再对数据应用任何更改,则所有节点都将同意数据值(即它们最终会同意),因此数据的读者最终将看到相同的值。
示例:两个节点 A 和 B (nA and nB) 拥有一个字符串的每个副本,该字符串通过操作进行更新read()
and write(string)
。假设每个人都有自己的客户(cliA and cliB)。假设最初两个节点存储相同的值“Joe”,但在某个时刻nA将其更新为“Frank”(调用write("Frank")
). Then nA会告诉nB该值已更新;由于两个值不同,因此出现了冲突,但可以使用某些策略(例如最后写入获胜)来解决nB终于将其记录也更新为“Frank”。在冲突解决之前cliA and cliB将看到不同版本的数据(read()
op 结果会有所不同),但最终两者都会再次看到相同的值。
请记住,如果两个节点同时更新其值,则冲突解决仍然是可能的,但会更加复杂。这就是 SEC 的闪光点。
强最终一致性这是 EC 的特殊情况,仅对某些数据类型有效。
假设共享的数据对象是一个计数器,并且更新是通过add(int value)
and substract(int value)
运营。在这种情况下,我们应用更新的顺序并不重要!所以如果两者nA and nB从计数器值 0 开始,如果然后 nA 运行add(10)
and nB runs substract(5)
(同时),它们只需要互相发送更新操作,而不关心冲突解决,最终确保它们达到相同的值(记住,相反,在前面的 EC 示例中,可以进行一些冲突解决)必需的)!
不幸的是,SEC 仅适用于具有特定属性(交换性等)的某些数据类型和操作。此类数据类型表示为无冲突复制数据类型 (CRDT) .
一致性强与另外两个截然不同。这里要求在更新操作时,所有节点在使新值对客户端可见之前就新值达成一致。这样,所有客户端“同时”都可以看到更新,因此他们将始终读取相同的值。现在这引入了更新操作中一些阻塞的要求。在 EC 和 SEC 中,一旦本地副本更新,更新操作就结束(然后该操作被广播到其他节点)。这里,直到所有节点就数据值达成一致之后,客户端更新才会返回,并且在完成此操作时,对该数据的任何副本的所有访问都被“锁定”(因此其他客户端读取被阻止)。在我们的 EC 示例中,如果cliA runs write("Frank")
, cliA将被阻止,直到双方同意更新nA and nB,然后它将对双方都可见cliA and cliB同时,即read()
从那时起操作应该返回相同的值。