用简单的英语最终一致性

我经常在不同的演讲中听到关于 NoSQL、数据网格等等的最终一致性。 最终一致性的定义似乎在很多方面都有所不同(甚至可能取决于具体的数据存储)。

谁能简单解释一下什么是一般意义上的最终一致性,而不是任何具体的数据存储?

41924 次浏览

最终一致性

  1. 我看了天气预报,得知明天要下雨。
  2. 我告诉你明天要下雨。
  3. 你的邻居告诉他的妻子明天将是晴天。
  4. 你告诉你的邻居明天要下雨。

最终,所有的服务器(你,我,你的邻居)都知道了真相(明天会下雨) ,但与此同时,客户(他的妻子)离开了,认为天气会很晴朗,尽管她要求一个或多个服务器(你和我)有更新的价值。

与严格遵守一致性/酸性相反:

  1. 你的银行存款余额是50美元。
  2. 你存100美元。
  3. 您的银行余额,从任何地方的自动取款机查询,是150美元。
  4. 你女儿用你的银行卡取了40美元。
  5. 您的银行余额,从任何地方的自动取款机查询,是110美元。

在任何时候,你的余额都不能反映除了你账户上所有交易的实际总额以外的任何东西。

返回文章页面为什么如此多的 NoSQL 系统会有最终一致性: 几乎所有的 NoSQL 系统都被设计成分布式的,而对于完全分布式系统来说,要保持严格的一致性会有超线性的开销(这意味着你只能在事情开始变慢之前扩展这么远,而当它们开始变慢时,你需要投入指数级的更多硬件来解决这个问题,以保持扩展)。

最终一致性

  1. 您的数据在多个服务器上进行复制
  2. 您的客户端可以访问任何服务器来检索数据
  3. 有人把一段数据写到其中一台服务器上,但还没有复制到其他服务器上
  4. 客户端使用数据访问服务器,并获得最新的副本
  5. 不同的客户端(甚至是同一个客户端)访问不同的服务器(还没有获得新副本的服务器) ,并获得旧副本

基本上,因为在多个服务器上复制数据需要时间,所以读取数据的请求可能会以新副本发送到服务器,然后以旧副本发送到服务器。术语“最终”意味着最终数据将被复制到所有服务器,因此它们都将拥有最新的副本。

如果你想要低延迟读取,最终一致性是必须的,因为响应服务器必须返回它自己的数据副本,而没有时间咨询其他服务器并就数据的内容达成共识。我写了一个 博客文章更详细地解释了这一点。

最终一致性更像是光谱。一方面你有很强的一致性,另一方面你有很强的最终一致性。在这两者之间有一些级别,比如 Snapshot、阅读我的文章、限制性陈旧。道格 · 特里在他关于棒球最终一致性的论文中有一个很好的解释 .

根据我的最终一致性,每次你从数据存储中读取数据的时候,你基本上可以容忍随机的数据。任何比这更好的内存一致性模型。例如,快照具有过时的数据,但如果再次读取,将返回相同的数据,因此它是可预测的。有时,应用程序可以容忍在给定时间内过时的数据,超过这个时间就需要一致的数据。

如果你观察一致性的意义,它更多地与一致性或缺乏偏差有关。因此,在非计算机系统术语中,它可能意味着对意外变化的容忍。这可以通过 ATM 机很好地解释。ATM 可能脱机,因此与核心系统的帐户余额不同。然而,对于显示一段时间内的不同余额是可以容忍的。一旦 ATM 上线,它可以与核心系统同步,并反映相同的平衡。所以 ATM 可以说最终是一致的。

当应用程序对一台计算机上的数据项进行更改时,该更改必须传播到其他副本。由于更改传播不是瞬时的,因此会有一段时间间隔,在此期间,一些副本会有最新的更改,而其他副本则不会。换句话说,这些副本将是相互矛盾的。然而,更改最终将传播到所有副本,因此术语“最终一致性”。术语“最终一致性”只是一种确认,即在将一台机器上所做的更改传播到所有其他副本时存在无限延迟。最终一致性在集中式(单拷贝)系统中没有意义或相关性,因为不需要传播。

来源: http://www.oracle.com/technetwork/products/nosqldb/documentation/consistency-explained-1659908.pdf

在简单的英语中,我们可以说: 虽然您的系统可能处于不一致的状态,但目标始终是为每个数据片段在某个点达到一致性。

认为您有一个应用程序及其副本。然后您必须向应用程序添加新的数据项。

enter image description here

然后应用程序将数据同步到下面显示的其他副本

enter image description here

与此同时,新客户端将从一个尚未更新的副本中获取数据。在这种情况下,他无法得到正确的最新数据。因为同步需要一些时间。在这种情况下,它没有 最终保持一致

问题是我们怎么能 最终保持一致

为此,我们使用中介应用程序来更新/创建/删除数据,并使用直接查询来读取数据。有助于使 最终保持一致

enter image description here enter image description here

最终一致性意味着更改需要时间传播,并且在每个操作之后,数据可能不处于相同的状态,即使是对于相同的操作或数据转换。当人们在与这样的系统交互时不知道自己在做什么时,这可能会导致非常糟糕的事情发生。

在理解这个概念之前,请不要实现业务关键文档数据存储。搞砸一个文档数据存储实现比修复一个关系模型要难得多,因为将要搞砸的基本事情根本无法修复,因为需要修复的事情根本不存在于生态系统中。重构机上存储的数据也比简单的 RDBMS ETL 转换困难得多。

并非所有的文档存储都是相同的。现在有些 MongoDB 确实支持某种类型的事务,但是迁移数据存储很可能与重新实现的开销相当。

警告: 不知道或不了解文档数据存储技术的开发人员甚至架构师都不敢承认这一点,因为他们害怕丢掉工作,但他们接受过关系数据库管理系统(RDBMS)方面的经典培训,而且只知道 ACID 系统(它能有多大的不同?)而不懂技术或不花时间学习的人,就会错过设计文档数据存储的机会。他们也可以尝试将其用作 RDBMS 或者缓存之类的东西。它们将把应该在整个文档上运行的原子事务分解为“关系”事务,而忘记了复制和延迟是事情,或者更糟糕的是,将第三方系统拖入“事务”。他们会这样做,这样他们的 RDBMS 就可以镜像他们的数据湖,不管它是否能工作,也不需要测试,因为他们知道他们在做什么。然后,当存储在单独文档(如“ order”)中的复杂对象的“ order item”比预期的少,或者根本没有订单时,他们会感到惊讶。但这种情况不会经常发生,或者不会经常发生,所以他们只会向前走。他们甚至可能无法在开发中解决这个问题。然后,他们将抛出“延迟”、“重试”和“检入”来伪造关系数据模型,而不是重新设计东西,这样做不会起作用,但会增加额外的复杂性,而且没有任何好处。但现在为时已晚——这个东西已经部署完毕,现在业务正在它上面运行。最终,整个系统将被抛弃,部门将被外包,其他人将维护它。它仍然不能正常工作,但是它们可以比当前的故障更廉价地失败。

Eventual consistency保证整个系统的一致性,但不是在任何时候。有一个不一致窗口,其中一个节点可能没有最新的值,但在查询时仍将返回有效的响应,即使该响应不准确。Cassandra 有一个环形系统,你的数据被分成不同的节点:

enter image description here

这些节点中的任何一个都可以充当应用程序的主接口点。因此不存在单点故障,因为这些节点中的任何一个都可以作为主 API 点。但这里有一个交易。因为任何节点都可以是主节点,所以需要在所有这些节点之间复制该数据,以保持最新。所以所有其他节点都需要知道什么在任何时候都在什么位置,这意味着对于这个体系结构,我们有 eventual consistency。因为数据在整个环中传播需要时间,通过系统中的每个节点。因此,在写入数据时,可能需要一点时间才能真正将刚才写入的数据读回来。也许数据被写入到一个节点,但是您正在从另一个节点读取数据,并且写入的数据还没有到达该另一个节点。

假设你每周日都把手机上的照片备份到云端。如果你在你的云端查看你周五的照片,你将看不到周一到周五之间拍摄的照片。你仍然得到一个响应,但不是一个更新的响应,但如果你检查你的云在周日晚上,你会看到你所有的照片。因此,通过电话和云服务的数据最终会达到一致性。