有人能简单地解释一下什么是 eventual consistency 吗?不涉及任何具体的数据存储方法,通俗易懂即可。
最终一致性:
最终,所有服务器(包括你、我和你的邻居)都知道真相(明天会下雨),但在此期间,客户端(你的邻居的妻子)却认为明天会晴天,尽管她询问时有一个或多个服务器(你和我)具有更实时的值。
与严格一致性/ACID合规相对:
在任何时候,你的余额都不能反映出除此时刻之前所有账户上的交易总和以外的任何内容。
为什么许多NoSQL系统具有最终一致性,是因为几乎所有这些系统都设计成分布式的,对于完全分布式系统来说,维护严格的一致性会产生超线性的开销(这意味着在事情开始变慢之前,你只能扩展到某个程度,在出现问题时,你需要投入指数级更多的硬件来保持扩展)。
最终一致性:
基本上,由于在多个服务器之间复制数据需要时间,因此读取数据的请求可能会发送到具有新副本的服务器,然后转移到具有旧副本的服务器。 "最终"一词意味着最终数据将被复制到所有服务器上,因此它们都将拥有最新的副本。
如果要进行低延迟读取,则必须具备最终一致性,因为响应服务器必须返回其自己的数据副本,并且没有时间在其他服务器上查询和达成关于数据内容的共识。我撰写了一篇博客文章更详细地解释了这一点。
最终一致性更像是一个光谱。在一端,你有强一致性,在另一端,你有最终一致性。在中间,有像快照、读取我的写入、有界陈旧度等级。Doug Terry 在他的论文 《通过棒球理解最终一致性》 中有一个很好的解释。
对我来说,最终一致性基本上是容忍每次从数据存储中读取随机数据以随机顺序出现。任何比这更好的都是更强的一致性模型。例如,快照具有过时的数据,但如果再次读取,则返回相同的数据,因此它是可预测的。有时应用程序可以容忍数据在给定时间内过时,超过这个时间就需要一致的数据。
如果你看一下一致性的含义,它更多地涉及到统一性或缺乏偏差。因此,在非计算机系统术语中,它可能意味着容忍意外变化。这可以通过 ATM 很好地解释。ATM 可能处于离线状态,因此与核心系统的账户余额不同。然而,在一段时间内显示不同的余额是可以容忍的。一旦 ATM 上线,它就可以与核心系统同步,并反映相同的余额。因此,可以说 ATM 最终是一致的。
最终一致性
保证了系统的一致性,但并非始终如此。存在一个不一致的时间窗口,在这个时间窗口内,某个节点可能没有最新的值,但在查询时仍会返回有效的响应,即使该响应不准确。Cassandra具有环形系统,将您的数据分割成不同的节点:
这些节点中的任何一个都可以作为应用程序的主要接口点。因此,由于这些节点中的任何一个都可以作为您的主要API点,所以没有单一故障点。但是在这里存在一个权衡。因为任何节点都可以是主节点,所以需要在所有这些节点之间复制数据以保持最新状态。因此,所有其他节点都需要始终知道数据的位置,这意味着作为这种架构的权衡,我们具有“最终一致性”。因为数据需要时间才能在系统中的每个节点中传播,所以当数据被写入时,可能需要一点时间才能实际读取刚刚写入的数据。也许数据被写入到一个节点,但是您正在从另一个节点读取它,并且该写入的数据尚未到达该节点。
假设您每个星期日将手机上的照片备份到云端。如果您在周五检查云端上的照片,则不会看到在周一至周五拍摄的照片。您仍然会得到响应,但不是更新后的响应,但如果您在周日晚上检查云端,则会看到所有照片。因此,您的电话和云服务上的数据最终达到一致性。