一年前,我写过一致性模型的文章的第一个版本。因为过后写的很匆忙,而且这个主题十分重要,值得更周密的看待,所以我并不是很称心。ACM Queue 为将其公布到本人感觉杂志上,所以请我认真斟酌。我得以借此机会改良这篇文章。本文就是最新的版本。
最终一致性 – 在寰球范畴内构建牢靠的分布式系统须要在一致性和可用性之间进行衡量。
亚马逊云计算的根底是诸如 S3(Simple Storage Service)、SimpleDB、EC2(Elastic Compute Cloud)等基础设施,为构建互联网规模级别计算平台和品种繁多的利用提供了资源。这些基础设施服务的要求十分严格,须要在安全性、可扩展性、可用性、性能和老本效益方面取得高分,与此同时还要继续为寰球数以百万计的客户提供服务。
在这些服务幕后,是寰球范畴内运行的大规模分布式系统。这种规模带来了额定的挑战。因为当零碎解决数以万亿计的申请时,通常状况下产生概率较低的的事件会必然产生,须要在零碎设计和架构中事后思考。鉴于这些零碎遍布寰球范畴,咱们通常应用复制技术来保障一致性的性能和高可用性。只管复制使咱们更靠近指标,却不能以齐全通明的形式实现这些指标。在许多状况下,这些服务的客户将面临服务外部应用复制技术的结果。
其中一种体现形式是提供的数据一致性的类型,特地是底层分布式系统为数据复制提供最终一致性模型时。在亚马逊设计这些大规模零碎时,应用了一套与大规模数据复制相干的领导准则和形象办法,并专一于高可用性和数据一致性之间的均衡。在本文中,我介绍了一些相干的背景常识,蕴含了咱们交付须要在寰球范畴内运行的牢靠分布式系统的办法。本文的晚期版本于 2007 年 12 月在 All Things Distributed 博客上发表,在读者的帮忙下失去了极大的改良。
历史视角
在现实世界里,只有一种一致性模型:当更新产生时,所有观察者都能看到那个更新。该模型第一次呈现难以实现的状况是在 70 年代末的数据库系统中。对于该主题最好的“期间作品”是 Bruce Lindsay 等人的”分布式数据库笔记”。它论述了数据库复制的基础性准则,并探讨了许多解决实现一致性的技术。其中许多技术都试图实现散发透明性——即对系统用户来说,仿佛只有一个零碎而不是多个合作零碎。在此期间,许多零碎采取的做法是偏向于让整个零碎失败,而非毁坏其透明度。
在 90 年代中期,随着大型互联网零碎的衰亡,这些做法被从新扫视。过后的人们开始思考可用性可能是这些零碎最重要的属性的想法,但他们正在为拿什么衡量而苦苦挣扎。加州大学伯克利分校零碎传授、过后的 Inktomi 负责人 Eric Brewer 在 2000 年 PODC(分布式计算原理)会议上的主题演讲中将不同的衡量联合在一起。他提出了 CAP 定理,该定理指出共享数据系统的三个属性——数据一致性、零碎可用性和对网络分区的容忍度——在任何给定工夫只能实现两个。更正式的认定能够在 Seth Gilbert 和 Nancy Lynch 2002 年的一篇论文中找到。
一个不容忍网络分区的零碎能够实现数据的一致性和可用性,通常通过应用事务协定来实现。要实现这一点,客户端和存储系统必须是同一环境的一部分;在某些状况下,它们作为一个整体失败,因而,客户端无奈察看到分区。一个重要的察看后果是,在较大的分布式系统中,网络分区是给定的;因而,一致性和可用性无奈同时实现。这意味着对于要删除的内容有两种抉择:放宽一致性将容许零碎在可分区条件下放弃高可用性,而将一致性作为优先级意味着在某些条件下零碎将不可用。
两种选项都要求客户端开发者理解零碎提供的内容。如果零碎强调一致性,开发者须要解决零碎可能不可用的事实,例如:写入。如果因为零碎不可用写操作失败,那么开发者不得不解决如何处理要写入的数据。如果零碎强调可用性,那么总能承受写操作,然而在某些状况下,读操作不会反映最近实现的写入的后果。而后,开发人员必须决定客户端是否须要始终拜访相对最新的更新。大量的应用程序能够解决略微古老的数据,并且在此模型下能够很好地提供服务。
原则上,ACID 属性(原子性、一致性、隔离性、持久性)中定义的事务零碎的一致性属性是一种不同的一致性保障。在 ACID 中,一致性是指当事务实现时,数据库处于统一状态的保障;例如,当从一个账户向另一个账户转账时,两个账户中持有的总金额不应扭转。在基于 ACID 的零碎中,这种一致性通常是编写事务的开发人员的责任,但能够由数据库治理完整性束缚来辅助。
一致性 —— 客户端和服务器
有两种对待一致性的办法。一种是从开发人员 / 客户的角度来看:他们如何察看数据更新。第二种形式来自服务器端:更新如何流经零碎以及零碎能够为更新提供什么保障。
客户端一致性
客户端具备以下组件:
- 一个存储系统。 目前咱们将其视为一个黑匣子,但人们应该假如在它幕后是大规模和高度分布式的,并且构建它是为了保障持久性和可用性。
- 过程 A。 这是一个对存储系统进行写入和读取的过程。
- 过程 B 和 C。 这两个过程独立于过程 A,对存储系统进行读写操作。它们是真正的过程还是同一过程中的线程无关紧要;重要的是它们是独立的,共享信息须要通信。
客户端一致性与观察者(在本例中为过程 A、B 或 C)如何以及何时查看对存储系统中的数据对象所做的更新无关。在以下阐明不同类型一致性的示例中,过程 A 对数据对象进行了更新:
- 强一致性(Strong consistency)。 更新实现后,任何后续拜访(通过 A、B 或 C)都将返回更新后的值。
- 弱一致性(Weak consistency)。 零碎不保障后续拜访将返回更新后的值。在返回值之前须要满足许多条件。更新和保障任何观察者总是看到更新值之间的时间段被称为不统一窗口。
- 最终一致性(Eventual consistency)。 弱一致性的一种非凡模式;存储系统保障如果没有对对象进行新的更新,最终所有拜访都将返回最初更新的值。如果没有产生故障,则能够依据通信提早、零碎负载以及复制计划中波及的正本数量等因素确定不统一窗口的最大大小。最风行的实现最终一致性的零碎是 DNS(域名零碎)。名称的更新依据配置的模式并联合工夫管制的缓存进行散发;最终,所有客户端都会看到更新。
最终一致性模型有许多须要思考的重要变种:
- 因果一致性(Causal consistency)。 如果过程 A 告诉过程 B 已更新数据项,则过程 B 的后续拜访将返回更新后的值,并且保障写入会取代较早的写入。与过程 A 没有因果关系的过程 C 的拜访遵循失常的最终一致性规定。
- 读写一致性(Read-your-writes consistency)。 这是一种重要的模型,其中过程 A 在更新数据项后,始终拜访更新的值并且永远不会看到旧值。这是因果一致性模型的一个特例。
- 会话一致性(Session consistency). 这是前一模型的实用版本,其中过程在会话上下文中拜访存储系统。只有会话存在,零碎就保障读写一致性。如果会话因为某种故障场景而终止,则须要创立新会话,并且保障会话之间不会重叠。
- 枯燥读一致性(Monotonic read consistency). 如果过程看到了对象的特定值,则任何后续拜访都将永远不会返回任何先前的值。
- 枯燥写一致性(Monotonic write consistency). 在这种状况下,零碎保障通过同一过程串行化写入。不保障这种一致性级别的零碎是出了名的难以编程。
上述个性能够组合。例如,能够将枯燥读与会话一致性相结合。从实际的角度来看,这两个个性(枯燥读取和读取你的写入)在最终一致性零碎中是最可取的,但并非总是必须的。开发者应用这两个个性能够更加简略的构建应用程序,同时容许存储系统放宽一致性并提供高可用性。
正如您从这些变种中看到的那样,可能存在多种不同的状况。是否能够解决结果取决于特定的应用程序。
最终一致性并不是极致分布式系统的某些深奥个性。许多提供主备可靠性的古代 RDBMS(关系数据库管理系统)以同步和异步模式实现复制技术。在同步模式下,正本更新是事务的一部分。在异步模式下,更新提早达到备份,通常是通过日志传送。在后一种模式下,如果主服务器在日志发送之前产生故障,从晋升为主的正本中读取,将呈现旧的、不统一的值。同样为了反对更好的可扩大读取性能,RDBMS 曾经开始提供从备份读取的能力,这是提供最终一致性保障的经典案例,其中不统一窗口取决于日志传送的周期。
服务器端一致性
在服务器端,咱们须要更深刻地理解更新如何流经零碎,以理解是什么使得零碎的开发人员能够感触到不同的模式。在开始之前,让咱们先建设一些定义:
N = 存储数据正本的节点数
W = 更新实现前须要确认收到更新的正本数
R = 通过读取操作拜访数据对象时分割的正本数
如果 W + R > N,那么写集和读集始终存在重叠,能够保障强一致性。在实现同步复制技术的主备 RDBMS 场景中:N=2、W=2、R=1,无论客户端从哪个正本读取,总能失去统一的后果。在启用了从备份读取的异步复制中,N=2、W=1、R=1。这种状况下 R + W = N,无奈保障一致性。
这些根本仲裁协定(quorum protocols)配置存在的问题是,当零碎因为故障而无奈写入 W 节点时,写入操作必须失败,这标记着零碎不可用。当 N = 3 和 W = 3 且只有两个节点可用时,零碎不得不使写入失败。
在高性能和高可用性的分布式存储系统中,正本的数量通常大于 2。仅关注容错的零碎通常应用 N = 3(W = 2、R = 2)的配置。须要提供十分高的读取负载服务的零碎,通常会复制超出容错所需的数据;N 能够是数十甚至数百节点,R 配置为 1,这样单次读取就能返回后果。关注一致性的零碎设置为 W = N 以应答更新,这可能会升高写入胜利的概率。对于关注容错但不关注一致性的零碎,常见配置是以 W = 1 运行,以取得最小的更新持久性,而后依附提早(流传)技术来更新其余正本。
如何配置 N、W 和 R 取决于具体情况以及须要优化的性能门路。在 R = 1 和 N = W 中,咱们针对读取状况进行了优化,在 W = 1 和 R = N 中,咱们针对疾速写入进行了优化。当然,在后一种状况下,呈现故障时无奈保障持久性,如果 W < (N + 1) / 2,当写集不重叠时,存在抵触写入的可能性。
当 W+R <= N 时呈现弱 / 最终一致性,这意味着读写集有可能不会重叠。如果这是一个通过三思而行的配置,而不是基于失败案例,那么将 R 设置为 1 以外的任何值简直没有意义。这产生在两种十分常见的状况下:第一种是后面提到的用于读扩大的大规模复制;第二种是数据拜访更简单的中央。在简略的键值模型中,比拟版本以确定写入零碎的最新值很容易,但在返回对象集的零碎中,确定正确的最新集更艰难。在大多数写入集小于正本集的零碎中,有一种机制以提早形式将更新利用于正本集中的其余节点。在所有正本都被更新之前的时间段是后面探讨的不统一窗口。如果 W+R <= N,则零碎容易从尚未收到更新的节点读取数据。
读写一致性、会话一致性和枯燥一致性是否实现,通常取决于客户端对与执行分布式协定服务器的“粘性”。如果每次都是同一台服务器,那么就比拟容易保障读写和枯燥读写。同一台服务器使得治理负载平衡和容错略微艰难一些,却是一个简略的解决方案。应用具备粘性的会话易于了解,并提供客户能够推理的裸露级别。
有时客户端实现读写和枯燥读取。通过在写入时增加版本,客户端会抛弃对上次看到的版本之前版本的读取。
当零碎中的某些节点无奈连贯到其余节点,但客户端组能够拜访这两个节点汇合时,就会产生分区。如果您应用经典的少数仲裁办法,则在另一个分区变得不可用时,具备复制集的 W 个节点的分区能够持续进行更新。读取集也是如此。假如这两个汇合重叠,依据定义,多数汇合将变得不可用。分区不常常产生,但它们的确产生在数据中心之间以及数据中心外部。
在某些应用程序中,任何分区的不可用都是不可承受的,重要的是能够让拜访该分区的客户端持续运行。在这种状况下,单方调配一组新的存储节点来接收数据,并在分区愈合时执行合并操作。例如,在亚马逊外部,购物车应用一种永远写入的零碎;在分区的状况下,即便原始购物车位于其余分区上,客户也能够持续将商品放入购物车。一旦分区复原,购物车应用程序将帮助存储系统合并购物车。
亚马逊 Dynamo
亚马逊的 Dynamo 就是这样一个零碎,将所有这些个性都置于应用程序体系结构的显式管制之下。它是一个键值存储系统,跟 AWS(Amazon’s Web Service)一样,在亚马逊电子商务平台的服务外部宽泛应用。Dynamo 的设计指标之一是容许应用程序的所有者、创立 Dynamo 存储系统实例者,在一致性、持久性、可用性和性能之间进行衡量,而 Dynamo 存储系统通常逾越多个数据中心。
总结
在大规模牢靠的分布式系统中,有两个必须容忍数据不统一的起因:在高并发条件下改善读写性能;以及解决大多数模型会导致局部零碎不可用的分区状况,即便节点已启动并正在运行。
不一致性是否可承受取决于客户端应用程序。在所有状况下,开发人员都须要意识到,一致性保障是由存储系统提供的,在开发应用程序时须要加以思考。最终一致性模型有许多理论的改良,例如会话一致性和枯燥读,它们给开发人员提供了更好的工具。很多时候,应用程序可能毫无问题地解决存储系统的最终一致性保障。一个特地风行的例子是一个网站,在这个网站中咱们能够有用户感知一致性的概念。在这种状况下,不统一窗口须要小于客户加载下一个页面的预期工夫。使得在预期下一次读取之前,将更新流传到整个零碎。
本文的指标是进步对工程零碎复杂性的意识,这些零碎须要在寰球范畴内运行,并且须要认真调优,以确保它们可能提供应用程序所需的持久性、可用性和性能。零碎设计者领有的工具之一就是一致性窗口的长度,在此期间,零碎的客户端可能会接触到大规模系统工程的实相。
<br/>
参考文献
- Brewer, E. A. 2000. Towards robust distributed systems (abstract). In Proceedings of the 19th Annual ACM Symposium on Principles of Distributed Computing (July 16-19, Portland, Oregon): 7
- A Conversation with Bruce Lindsay. 2004. ACM Queue 2(8): 22-33.
- DeCandia, G., Hastorun, D., Jampani, M., Kakulapati, G., Lakshman, A., Pilchin, A., Sivasubramanian, S., Vosshall, P., Vogels, W. 2007. Dynamo: Amazon’s highly available key-value store. In Proceedings of the 21st ACM Symposium on Operating Systems Principles (Stevenson, Washington, October).
- Gilbert , S., Lynch, N. 2002. Brewer’s conjecture and the feasibility of consistent, available, partition-tolerant Web services. ACM SIGACT News 33(2).
- Lindsay, B. G., Selinger, P. G., et al. 1980. Notes on distributed databases. In _Distributed Data Bases, ed. I_. W. Draffan and F. Poole, 247-284. Cambridge: Cambridge University Press. Also available as IBM Research Report RJ2517, San Jose, California (July 1979).
原文链接:http://www.allthingsdistributed.com/2008/12/eventually_consistent.html
本文作者 :cyningsun
本文地址 :https://www.cyningsun.com/06-26-2021/eventually-consistent-cn.html
版权申明:本博客所有文章除特地申明外,均采纳 CC BY-NC-ND 3.0 CN 许可协定。转载请注明出处!