查看 Pat 的
关于分布式系统的零散思考
pathelland.substack.com
40 多年来,快速失败一直是实现容错的主要方式。在这种方法中,某种机制负责确保每个组件都已启动、正常运行并响应工作。只要它仍然存活且健康,您就可以继续前进;当组件出现问题时,它将从系统中移除,其余组件重新组织自身以继续运行。对于许多(但并非所有)系统来说,这就是您在部件发生故障时确保系统保持运行的方式。
随着行业转向利用云计算,这变得越来越具有挑战性。首先,我热爱云计算,并认为它是向前迈出的重要一步。然而,当我们创建健壮的解决方案时,由于各个组件遇到称为灰度故障的新兴挑战,我们创建健壮解决方案的方式正面临压力。在灰度故障中,服务器或网络的一部分不会快速失败,而是开始运行缓慢。运行缓慢比快速失败糟糕得多。缓慢的组件,有时以低于正常速度百分之一的速度运行,可能足够健康以说“我还在!”,但又足够慢以阻塞所有工作。这使得快速失败方案变得脆弱。
在很久以前,服务器的硬件位于您数据中心内严格控制的环境中。一些销售人员说服您,您需要最好、最昂贵、最具弹性的服务器。您知道,如果您购买了那些服务器,您就不会被解雇。连接这些服务器意味着您拥有一个仅支持您自己内容的本地网络。您可以确保本地网络中运行的流量不会太拥挤。因此,各个服务器可以可预测地响应高优先级消息,例如“你好吗,好伙伴?” 这些消息像周日凌晨 4 点在旧金山 101 公路上行驶一样,飞速穿过过度配置的网络。
利用这些对健康询问的极大概率的响应,监管服务器可以轻松地对健康或疾病施加规则。对于此健康检查的答复有一个预期时间。如果响应时间过长,您将再次尝试。在没有答案的情况下等待的时间越长,滞后的服务器就越可能真正生病。经过相当少的尝试后,您可以放弃并宣布破坏派对的人被排除在派对之外。是的,该决定是概率性的,但几率真的非常好,您可以很快做出决定。
接下来,重要的是要果断地驱逐叛变节点。向其发送停止和终止的消息可能不会产生任何影响。这通常称为 STONITH(击毙另一个节点)。有时另一个节点很顽固,STONITH 无效。另一个技巧是确保被驱逐的节点不会造成任何危害。如果您可以保证任性的节点不能在节点外部进行任何更改,那么团队的其余成员就可以继续他们的生活。让它在单独监禁中腐烂。
通过这种方式,您可以检测到节点已失败,并确保它已完全失败。在过去,做到这一点并不需要太长时间。
有一个悖论称为布里丹之驴,以 14 世纪哲学家让·布里丹7的名字命名。布里丹之驴突出了决定论概念或每个事件都源自先前事件的信念中固有的明显矛盾。该悖论提出,将一头非常饥饿的驴子放在两捆干草的正中间。假设驴子会去最近的资源,它会被饿死。
在电子学中,有一种现象称为亚稳态,这意味着系统可能在无限时间内处于不稳定状态。为了使有效信号作为电路的输出,它必须驻留在一定的电压或电流水平内。如果输出落在中间的灰色区域,则下一个电路会发生奇怪的事情。它也可能做一些奇怪的事情。
这种亚稳态是异步电路固有的。由于您不知道输入信号的定时,因此有时各种输入会同时到达,并且电路无法在两捆干草之间做出决定。异步数字系统通常会在输入信号中添加仲裁器,以确保信号有序,从而避免亚稳态。在同步设备上的时钟域内,时钟可确保提供给逻辑电路的输入的定时,从而避免亚稳态问题。当同步电路接收传入的异步信号时,特殊的同步器会工作,以使亚稳态的可能性变得非常小,但仍然可能发生。
将分布式系统进行提升和转移到复杂的云计算环境,会给分布式系统设计带来一系列新问题。在虚拟机中运行服务器以优惠的价格提供了大量有价值的计算,但它可能会按照自己的时间表进行。嘈杂邻居问题是指您的虚拟机的容量会发生变化,因为它与同一物理服务器上的其他虚拟机竞争资源。多核服务器增加了乐趣,因为它们的协调可能会也可能不会阻止您希望发送的消息。通过云网络基础设施的行程可能会遇到拥塞引起的通信,就像美国邮政服务一样。这使得基于定时的快速失败成为概率性的。它一直都是概率性的,但现在几率已从极小的概率转变为难以调试的罕见概率。
以前,当分布式系统由可预测的服务器和网络组成时,您可以很好地了解您的同伴会多快回复健康检查。利用这种预期,您可以快速删除不健康的节点,而很少删除健康的节点。这是一个概率游戏,您做出正确决定的几率非常高。这很像电路在时钟域内工作以避免亚稳态行为。
服务器和/或往返服务器的消息并非总是以可预测的速度工作。这很像删除同步电路内的时钟,使其成为异步数字系统。抑制和消除亚稳态的可能性已变得非常低。
考虑一个杂耍团队在舞台上处理数十个球。如果其中一些球以不相关的方式进入慢动作,则可能会出现问题。杂耍演员有自己的时间框架,他们会在球到达时看到球到达。在短时间内,这可能是有道理的。当每个杂耍演员的时间在他们不知情的情况下加速和减速时,跨团队进行基于时间的交互变得几乎不可能。
当分布式系统的旧部署被提升并转移到云端时,就像去嘉年华的娱乐区一样。时间和距离会失真,快速失败的决策变得不可预测。当服务器没有大致按照同一个鼓手的节拍前进时,分布式系统算法可能会变得亚稳态。
更糟糕的是,大多数系统都依赖于数据中心中的其他系统。HDFS(Hadoop 分布式文件系统)依赖于 Apache ZooKeeper。1 ZooKeeper 和其他服务依赖于 DNS(域名系统)。这些系统中的每一个都有超时和重试,这可能会导致级联延迟、超时和故障。这是亚稳态的另一种形式,它会加剧问题而不是抑制问题。
当这种亚稳态干扰分布式系统中的主节点或领导者时,您无法快速访问许多系统所需的“完美真理”或线性化。可用性可能会受到很大影响。
让我们将注意力转向不强制要求完美最新答案的算法的重要性。当对用户的请求基于包含陈旧状态的副本池时,任何一个副本都足够了。使用新状态更新副本的后台工作可能会落后很多,但这没关系。“还不错”的一个极好的例子可以在您阅读在线零售中的产品目录或产品评论的副本时找到。同样,在 Web 搜索中,您可以访问查询中搜索词的所有分片。每个请求都返回绝对最新的结果并非必不可少的。“还不错”已经非常好了。
当向具有这些缓存副本的服务器池发送工作时,客户端可以超时并重试以限制延迟。它实际上并不太关心单个服务器的健康状况,因为客户端可以通过使用称为对冲3的技术重试从另一个服务器获得好的答案。在一段时间内,无响应服务器的状态并不太重要。让它处于亚稳态,同时处于不确定状态是可以的。坦率地说,您不需要关于服务器在集群中的成员资格的完美答案。随着时间的推移,它会开始表现得更好,或者它将被踢出集群。不需要急于获得完美的答案。
对于日志记录,也出现了类似的新兴容错算法。Apache BookKeeper2 是一个开源日志记录子系统,其中向日志中附加新记录的写入操作不需要到达包含日志副本的所有日志服务器。到达必需的子集就足够了。同样,Amazon Aurora8,9 通过 AWS(Amazon Web Services)提供,它在集中式服务器中运行数据库,但将其更新发送到存储服务器池。由于并非所有存储服务器都需要及时响应,因此 BookKeeper 和 Aurora 使用的方法在服务器延迟方面具有显着更高的弹性。单个副本可以在自己的时间扭曲中生存,而更广泛的分布式算法可以愉快地进行。
我认为这就像河流中水流绕过岩石一样。完成足够的工作比坚持完成所有工作更具弹性。
当传统算法依赖于集群成员资格的完美知识时,您能做什么?许多系统的构建都期望完美的知识能够给出完美的答案。例如,HDFS6 具有 NameNode,它负责数据页面的分配。除非 HDFS 知道您一次拥有零个或一个主 NameNode,否则文件系统可能会损坏。
当一台服务器快速失败时,它会被替换,数据在集群中四处移动,很快您就可以恢复业务。
HDFS 依赖于快速失败作为其活动性模型。我担心继续使用快速失败的能力,并且仍然遵循老式天美时手表广告的座右铭:“经得起折腾,不停运转。”
嗯……当在超现实世界之上运行时,某些算法确实是稳定的。但是,有些则不然。如果趋向亚稳态集群的趋势持续下去,那么任何依赖于一组固定的、响应迅速的服务器来传递强一致性线性化数据的算法都将面临越来越多的挑战。
集群的某些部分可能感知到与其他部分的时间差异,原因有很多:
• 服务器或 VM 在一段时间内未获得预期的计算量。
• 多核服务器在回答您的问题之前进行内部协调或停顿。
• 网络未向一对服务器提供其公平份额的带宽,导致延迟。
• 数据中心中的硬件行为不可预测,尤其是在这些组件的价格被压低时。5
• 越来越依赖其他服务(例如,ZooKeeper 或 DNS),这可能会因超时而导致级联混乱。
所有这些挑战都在大型、复杂和相互交织的环境中复合。
我想强调的是,我认为这是一件好事。虽然在我的梦想中,如果有一条专用高速公路车道供我从办公室通勤回家,那将是很棒的,但这实际上是不切实际的。相反,我们共享高速公路车道,尽管开放式排队网络中存在固有延迟风险,该网络允许大量传入流量且没有任何约束。我们中没有多少人可以建造一条专供个人使用的高速公路;因此,我们共享。云计算是共享。
现实生活中也是如此。如果您住在一个步行通勤回家的小镇,您可以预测每天晚上 6:23 准时走进前门。当您搬到有电梯、停车场和高速公路要穿越的大城市时,就很难精确地安排您的到达时间。
• 我们如何才能弥补云环境中亚稳态的这些问题?添加资源是否有帮助?
• 在社会上,人类有一种过度消耗资源的倾向,直到出现问题。我们是否总是会屈服于公地悲剧,并吸走所有空闲资源,直到我们处于亚稳态?
• 哪些算法可以为我们提供清晰明了的线性化更新,并在 99.9% 的时间内实现快速延迟?99.999% 的时间怎么样?当环境承受压力时,这些算法如何响应?
• 我们如何才能从对亚稳态敏感的算法演变为能够容忍和抑制大多数亚稳态的世界?
1. Apache 软件基金会。2010-2020。欢迎来到 Apache ZooKeeper;https://zookeeper.net.cn。
2. Apache 软件基金会。2016-2021。BookKeeper 概念和架构;http://bookkeeper.apache.org/docs/4.5.1/getting-started/concepts/。
3. Dean, J., Barroso, L. A. 2013。大规模尾部延迟。《 通讯》56(2), 74-80;https://cacm.acm.org/magazines/2013/2/160173-the-tail-at-scale/fulltext。
4. Gray, J. 1985。为什么计算机停止工作以及可以采取哪些措施?。《Tandem 技术报告 TR 85.7》;https://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf
5. Gunawi, H. S., et al. 2018。大规模的慢速失败:大型生产系统中硬件性能故障的证据。《第 16 届 Usenix 文件和存储技术会议论文集》;https://www.usenix.org/system/files/conference/fast18/fast18-gunawi.pdf。
6. Hadoop。2021。HDFS 架构指南;https://hadoop.apache.ac.cn/docs/r1.2.1/hdfs_design.html。
7. Lamport, L. 2012。布里丹原理。《物理学基础》42;https://lamport.azurewebsites.net/pubs/buridan.pdf
8. Verbitski, A., et al. 2017。Amazon Aurora:高吞吐量云原生关系数据库的设计考虑因素。《 国际数据管理会议论文集》,1041-1052;https://dl.acm.org/doi/pdf/10.1145/3035918.3056101。
9. Verbitski, A., et al. 2018。Amazon Aurora:关于避免分布式共识进行 I/O、提交和成员资格更改。《 国际数据管理会议论文集》,789-796;http://pages.cs.wisc.edu/~yxy/cs839-s20/papers/aurora-sigmod-18.pdf。
Pat Helland 自 1978 年以来一直从事事务系统、数据库、应用程序平台、分布式系统、容错系统和消息传递系统的实施工作。为了娱乐,他偶尔撰写技术论文。他在 Salesforce 工作。他的博客位于 pathelland.substack.com。
版权所有 © 2021,所有者/作者所有。出版权已许可给 。
最初发表于 Queue 第 19 卷,第 1 期—
在 数字图书馆中评论本文
Martin Kleppmann, Alastair R. Beresford, Boerge Svingen - 在线事件处理
对跨异构存储技术的分布式事务的支持要么不存在,要么在操作和性能特性方面表现不佳。相比之下,OLEP 越来越多地用于在这些环境中提供良好的性能和强大的数据一致性保证。在数据系统中,日志通常用作内部实现细节。OLEP 方法有所不同:它使用事件日志而不是事务作为数据管理的主要应用程序编程模型。传统数据库仍然被使用,但它们的写入来自日志而不是直接来自应用程序。OLEP 的使用不仅仅是开发人员的实用主义,而且它还提供了许多优势。
Andrew Leung, Andrew Spyker, Tim Bozarth - Titus:将容器引入 Netflix 云
我们相信,我们的方法使 Netflix 能够快速采用容器并从中受益。尽管细节可能特定于 Netflix,但通过与现有基础设施集成并与合适的早期采用者合作来提供低摩擦容器采用的方法,对于任何希望采用容器的组织来说,都可能是一种成功的策略。
Marius Eriksen - 大规模函数式
现代服务器软件在开发和运营方面都要求很高:它必须在所有时间和所有地点都可用;它必须在毫秒内回复用户请求;它必须快速响应容量需求;它必须处理大量数据和更多流量;它必须快速适应不断变化的产品需求;并且在许多情况下,它必须容纳一个庞大的工程组织,其众多工程师就像一个又大又乱的厨房里的谚语厨师。
Caitie McCaffrey - 分布式系统的验证
莱斯利·兰波特 (Leslie Lamport) 因其在分布式系统方面的开创性工作而闻名,他曾说过一句名言:“分布式系统是指,即使您根本不知道存在的计算机发生故障,也可能导致您自己的计算机无法使用。” 鉴于这种黯淡的前景和大量可能的故障,您甚至如何开始验证和确认您构建的分布式系统正在做正确的事情?