亚马逊 CTO Werner Vogels 经典博文:关于 Eventually Consistent 最终一致性 | 编译
6819
2016-08-31 19:32
文章摘要:编者:T 客汇 张苏月 杨丽,原作 关键词:分布式系统,服务,数据类型 网站:www.tikehui.com 编者注:本文是 Vogels 博客中经典的一篇博文,在这篇文章中,写到了亚马逊在全球范围内运作可靠的分布式系统的方法和相关背景。 最终一致性,即在世界范围内建立可靠的分布式系统,需要在连贯性和可用性之
编者:T 客汇 张苏月 杨丽,原作

关键词:分布式系统,服务,数据类型

网站:www.tikehui.com

编者注:本文是 Vogels 博客中经典的一篇博文,在这篇文章中,写到了亚马逊在全球范围内运作可靠的分布式系统的方法和相关背景。

eventually-consistent-1

 

最终一致性,即在世界范围内建立可靠的分布式系统,需要在连贯性和可用性之间达到一种平衡。

亚马逊云计算的基础设施服务,如 Amazon 的 S3,是一种简单存储服务,SimpleDB 和 EC2,一种弹性计算云,提供了构建互联网规模的计算平台资源和各种应用的基础。

这些基础设施服务的要求是非常严格的,他们需要有优异的安全性,可扩展性,可用性,性能和成本效益,并且当其同时为数以百万计的全球各地的客户不断服务时,他们也需要满足这些要求。

在其覆盖范围内,这些服务是一个能在全球范围内运行的庞大分布式系统。这种规模带来了额外的挑战,当一个系统计算万亿和数以万亿计的要求时。鉴于这些系统分布在世界范围内,我们运用无处不在的复制技术来保证系统的稳定性和高可用性。虽然复制使我们更接近目标,但它不能在一个完全透明的方式下实现,而且在一些条件下,使用这些服务的客户将面临使用内部服务的复制技术带来的后果。

特别是当底层的分布式系统为数据复制提供了一个最终一致性模型的时候。亚马逊设计这些大型系统时,我们使用一组与大规模数据复制相关的指导原则以及抽象概念,并专注于高可用性和数据一致性之间的权衡。

本文提出了一些可以帮助我们提供需要在全球范围内运作可靠的分布式系统的方法相关的背景。



历史展望


在一个理想的状态下可能只有一个一致性模型:当一个更新完成了所有的观察者都会看到这个更新。这个概念第一次出现是在 70 年代末的数据库系统中。这一主题最好的「时期片段」是由琳赛布鲁斯等人所写的「分布式数据库上的笔记」。它列出了数据库复制的基本原则,并讨论了一些处理实现一致性的技术。许多这些技术试图实现分配的透明度,也就是,对系统的使用者来说,似乎只有一个系统,而不是许多合作系统。在这段时间内许多系统采取这种方法,它是更好地破坏完整的系统,而不是打破这种透明度。

在 90 年代中期,随着大型互联网系统的兴起,这些做法被重新审视。当时人们开始考虑可用性可能是这些系统中最重要的属性,但他们正在努力找出与之相平衡的东西。Eric Brewer,加利福尼亚大学系统教授,和 Berkeley,当时 Inktomi 的发起者,在 2000 年的分布式计算原理会议上带来了不同的关于权衡的主题演讲. 他提出的 CAP 定理,表明共享数据系统的三个属性:数据一致性,系统的可用性,和宽容网络分区,其中在任何给定的时间内只有两个可以实现。

一个不能够容忍网络分区的系统可以实现数据的一致性和可用性,并且经常通过使用事务协议来实现。要实现这项工作,客户端和存储系统必须是同一个环境的一部分;在某些情况下,它们作为一个整体会失败,因此,客户端不能观察分区。一个重要的观察是,在更大的分布式系统,网络分区是一个给定的,因此,一致性和可用性不能同时实现。这意味着关于放弃什么有两个选择:放松一致性可以让系统在分区的条件下保持高可用性,而优先权是指在一定条件下系统不可用。

这两个选项都要求客户端开发人员清楚地知道系统提供的是什么。如果系统强调一致性,开发人员必须处理系统可能无法使用的事实,例如,写。如果因为系统不可用导致写失败,则开发者将要处理什么样的数据被写入。如果系统强调可用性,它可能总是接受写,但在一定条件下,一个阅读将不会反映最近完成的写的结果。然后,开发人员必须决定客户端是否总是需要访问最新的更新。有一系列的应用程序,可以处理稍陈旧的数据,而且在这个模型下他们可以更好地服务。

原则上交易系统一致性的定义被划分在 ACID 属性中(原子性,一致性,隔离性,持久性),这是一种不同的一致性保证类型。在 ACID 中,一致性涉及到保证当一个事务完成时数据库处于一致的状态;例如,当把钱从一个帐户转移到另一个帐户时,在两个帐户中持有的总金额不应该改变。在基于 ACID 的系统中,这种一致性通常是编写事务的开发人员责任,但可以通过数据库管理完整性约束来辅助。



客户端和服务器的一致性


看待「一致性」有两种方法。一个是从开发人员/客户端的角度来看:他们如何观察数据更新。第二种方法是从服务器端:如何通过系统的更新流程,是什么保证系统更新。

客户端一致性,客户端有这些组件:

存储系统。目前,我们将把它作为一个黑匣子,但应该假设,在覆盖范围内,它是一个大规模、高度分布的东西,它的建立是为了保证耐久性和可用性。

进程 A。这是一个从存储系统中写入和读取的过程。

进程 B 和 C。这两个过程是进程 A 的独立,从存储系统中写入和读取。在同一个过程中这些是否都是真正的进程或线程是不相关的,重要的是,他们是独立的,需要沟通,以共享信息。

客户端的一致性与观察者如何以及何时看到在存储系统中的数据对象的更新有关。下面的示例中说明了不同类型的一致性,进程 A 已对数据对象进行了更新:

强一致性。更新完成后,任何后续访问将返回更新后的值。

弱一致性。该系统不保证后续访问将返回更新后的值。许多条件需要在值返回之前被满足。在更新和保证任何观察者总是看到被更新的值之间的周期被称为不一致的窗口。

最终一致性。这是一个弱一致性的特定形式;存储系统保证如果没有目标进行新的更新,最终所有的访问将返回最后一次更新的值。如果没有发生故障,不一致窗口的最大尺寸可以基于一些因素如通信延迟,系统上的负载,和复制计划中涉及的副本的数量来确定。最常见的实现最终一致性的系统是 DNS(域名系统)。根据配置的模式和与时间控制的高速缓存相结合的更新的名称;最终,所有客户端都将看到更新。

最终一致性模型有一些重要的变化需要考虑:

因果一致性。如果过程 A 通知进程 B 它更新了一个数据项,进程 B 的后续访问将返回更新后的值。通过一个与 A 没有因果关系的过程 C 的访问,是受正常的最终一致性规则的驱使。

读写一致性。这是一个重要的模型,在这个模型中进程 A,在更新了一个数据项后,总是访问更新的值,将永远不会看到一个旧值。这是一个特殊的因果一致性模型情况下。

会话一致性。这是一个实用版本的前一个模型,其中一个进程在会话上下文中访问存储系统。只要会话存在,系统就会保证读写的一致性。如果会话因为某些故障终止,需要创建一个新的会话,并且保证不与会话重叠。

单调读一致性。如果一个进程为对象设定一个特定的值,任何后续的访问将永远不会返回以前的值。

单调写一致性。在这种情况下,系统通过同样的过程保证序列化的写。不保证这一水平的一致性的系统对程序来说还是很难的。

很多这些特性可以进行组合。例如,可以使单调读取与会话一致性结合。从实际的角度来看这两个属性在最终一致性系统最可取(单调读取和读取所写),但并非总是必需的。这两个特性使它为开发者构建应用程序变得简单,同时允许存储系统降低一致性和提供高可用性。

你可以从这些变化中看到,相当多的不同方案是可能的。这取决于特定的应用之一是否可以处理相应后果。

最终一致性不是分布式系统的特有本质属性。许多现代的 RDBMS(关系数据库管理系统)提供初级备份可靠性,在同步和异步模式下实现其复制技术。在同步模式下,复制更新是处理的一部分。在异步模式下,更新以延迟的方式完成备份,往往是通过日志传送。在后一种模式下,如果日志上传之前,主服务器发生故障,那么从升级备份读取会产生不一致旧的价值。还支持更好可扩展的读取性能,RDBMS 中已经开始提供备份读取服务,这是提供最终一致性保证的经典模式,不一致性窗口取决于日志传送的周期性。



服务器端一致性


在服务器端,我们需要深入探究系统如何更新,是什么驱动不同的模式,谁使用该系统。在开始之前下几个定义:

N =表示存储数据副本的节点数目

W =需要在更新完成之前,确认收到更新的副本数量

R =当数据对象是通过一个读取操作访问时的副本数量

如果 W + R> N,那么写集合与读始终设置重叠,谁也无法保证强一致性。在主要的备份的 RDBMS 方案中,它实现了同步复制,N = 2,W = 2,R = 1。无论从哪里客户端读取副本,它总是会得到一致答案。在异步复制下启用备份的读取,N = 2,W = 1,R = 1。在这种情况下,R + W = N,并且一致性不能保证。

这些配置中的问题,是基本的仲裁协议。当系统因故障不能写入到 W 节点,那么所述写操作失败,意味着系统不可用。用 N = 3W = 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 配置几乎没有道理。这发生在两个常见情况:第一个是前面提到的读取扩展复制;第二个是数据存取更加复杂。在一个简单的键 - 值模型中,进行版本比较以确定写入系统的最新值很容易,但在返回对象集的系统中,更难的是确定最新一组应该是什么。在大多数系统中写入集比副本集小,应用更新到副本的集中剩余节点的系统呈现。直到所有的副本已更新周期,这是之前所提到的不一致性窗口。当 w + R <= N,则系统很容易受到来自尚未收到更新的节点读取。

是否读取写入,会话和单调一致性取决于在一般在客户端上的「黏性」,服务器执行该分布式协议。如果每次在同一台服务器,则这是比较容易保证读取写入和单调读取。这使得管理负载平衡和容错功能变得有点难,但它是一个简单的解决方案。

有时,客户端实现读取写入和单调读取。通过在添加写入版本中,客户端丢弃了最后所看到的版本的值的读取。

分区发生在系统中的一些节点无法到达其他节点,但两组配置可接触到客户端。如果使用的是经典的多数仲裁的方式,那么出现此副本集 W 的节点分区可以继续,而其他分区则不能更新。读取配置同样如此。鉴于这两组配置重叠,通过定义少数集变得不可用。分区不频繁发生,但在数据中心以及内部数据中心之间发生。

在一些应用中的任何分区的不可用性是不能接受的,但重要的是,可以达到该分区的客户端取得进展。在这种情况下,双方分配一组新的存储节点以接收数据,一个合并操作在分隔修复时执行。例如,亚马逊在购物车使用这种写始终制度;在分区的情况下,客户可以继续放物品的购物即使原车在其他分区。一旦分区修复,购物车车应用程序以合并购物车协助存储系统。

Amazon 服务平台中的许多服务只需要主键访问数据存储。对于许多服务, 如提供最畅销书排行榜, 购物车, 客户的偏好, 会话管理, 销售等级, 产品目录, 常见的使用关系数据库的模式会导致效率低下, 有限的可扩展性和可用性。Dynamo 提供了一个简单的主键唯一的接口, 以满足这些应用的要求。Dynamo 的主要贡献是整合这些技术提供一种最终一致性的存储方案, 并证明其可以满足产品化的需求。



提升对工程系统复杂性的认识


在大规模可靠的分布式系统中必须接受数据不一致的原因有两个:提高读写高并发条件下的性能;处理分区情况下,大多数模型将会使用不可用系统的一部分,即使节点启动并运行。

无论是否不一致都可以接受,这取决于客户端应用程序。在所有情况下,开发者需要意识到:存储系统所保证了一致性,而开发应用程序时也需要考虑这一点。最终一致性模型有大量的实际改进,如会话一致性和单调读取,这就为开发者提供更好的工具。很多情况下,应用程序能够保证处理存储系统的最终一致性不出问题。特殊情况下,网站中我们可以有用户感知的一致性概念。在这种情况下不一致窗口需要比预期中顾客返回下一个页面的加载时间短。这允许通过该系统传播的更新要早于下一次预计时间。

这篇文章的目的是提高人们对需要在全球范围内进行操作并仔细调整的工程系统复杂性的认识。他们因此能够满足耐用、可用、高性能的产品应用。其中一个系统设计者的工具是一致窗口,在此期间,系统的客户端可能会接触到大型系统工程的实际情况。


版权声明:

凡本网内容请注明来源:T媒体(http://www.cniteyes.com)”的所有原创作品,版权均属于易信视界(北京)信息科技有限公司所有,未经本网书面授权,不得转载、摘编或以其它方式使用上述作品。

本网书面授权使用作品的,应在授权范围内使用,并按双方协议注明作品来源。违反上述声明者,易信视界(北京)信息科技有限公司将追究其相关法律责任。

评论