看看 Pat 的
关于分布式系统的零散思考

pathelland.substack.com

逃离奇点

  下载本文的 PDF 版本 PDF

逃离奇点

这不再是你祖母的数据库了

副作用,置于首位!

一个系统的副作用是另一个系统的命脉。


Pat Helland

我们根据计算的后果来思考计算。大型 MapReduce 作业返回一个大型结果。Web 交互显示信息。企业应用程序更新数据库并返回答案。这些是我们工作的理由。

我们很少讨论的是我们预期工作的副作用。副作用可能是不希望的,或者它们实际上可能在系统的不同层级引起期望的行为。本专栏指出了一些有趣的模式,在我们构建和使用系统时需要牢记。

抽象层

在构建系统时,我们会遇到许多抽象层。数据中心提供电力、网络、冷却和防雨保护。服务器提供 DRAM(动态随机存取存储器)、SSD(固态驱动器)、网络、计算、HDD(硬盘驱动器)等等。操作系统提供进程、虚拟内存、文件系统等等。

应用程序平台是主观术语:应用程序是在我之上运行的东西;平台是我在其之上运行的东西。

例如,内存管理位于大多数应用程序代码之下的抽象层中。当从堆中分配内存时,应用程序关心的是 mallocfree 或某些等效项。它根本不在乎内存是如何管理的,甚至在哪里。应用程序当然不关心堆的碎片。

TMI

在过去的几十年里,短语 TMI,意思是信息过多,已经进入词汇表。它通常指的是你已经听到并希望能够没听过的关于某人个人生活或卫生的知识。当你的叔公告诉你他的消化问题时,那就是 TMI!

TMI 也可以指你真的不想知道的关于你从应用程序中调用的另一个子系统的东西。

副作用是一个花哨的计算机科学术语,表示 TMI。

许多地方的副作用

我们在许多、许多地方的许多、许多抽象层级都看到了副作用。我们甚至在计算机以外的生活中也看到了副作用。以下是一些需要思考的例子

• 微服务的消息输入和输出通常会被记录下来用于监控目的。

• 对任何资源的竞争都可能导致其他竞争工作的拥塞和延迟。这非常像你在球赛结束时尝试在高速公路上开车时遇到的倒霉情况。

• 进入微服务的流量可能导致堆碎片,从而影响堆中垃圾被回收时下一个请求的响应速度。

• 写入磁盘可能导致文件系统变满。下一个请求受到影响。

• 我可能会预订飞机上的座位,导致其他人的下一个请求失败。我稍后取消并且不使用座位也没关系。另一位乘客仍然会失去机会,并且无法乘坐该航班。

这些示例中的每一个都可能由随后在更高抽象层级撤消或中止的工作驱动。从更高层级的角度来看,逻辑上,工作被撤消了。尽管如此,较低层级仍然存在持久性变化,并且对于上层级来说是 TMI。

事务由观察者决定

事务一词用于描述一些要么全部发生要么全部不发生的更改。ACID 事务1,2 指的是那些原子性、一致性、隔离性和持久性的事务。这些属性确保了一次只进行一项更改的可靠性,并且最常与数据库和数据库事务相关联。事务是一个令人着迷的工具——也是我 38 年职业生涯中花费了很大一部分时间研究的工具。

事实证明,事务经常由不同抽象层级的其他事务组成。这被称为开放式嵌套事务4 在开放式嵌套事务中,较高层级的事务由多个较低层级的事务组成。为了中止较高层级的事务,系统可能需要发出补偿性的较低层级事务,以撤消较高层级事务的效果。

Side Effects, Front and Center!

示例 1:欧洲之旅

现在,让我们考虑一下简单的欧洲商务旅行可能产生的一些副作用。

• 我预订了巴黎一家酒店周三晚上的住宿。这是我为期一周的欧洲旅行预订机票、汽车和酒店的一部分。

• 预订导致酒店入住率超过阈值,因此需要更多的员工和餐厅食物。

• 酒店餐厅向杂货店订购了周二的新一批货物。

• 杂货店致电运输公司,要求周二送货。

• 运输公司注意到预计的汽油燃料供应短缺,并订购了更多周一使用的燃料。

• 然后我取消了我的欧洲之旅。

我的预订引起了一系列我没有看到的级联效应。实际上,告诉我这些真的会是 TMI,给我带来很大的困惑。此外,即使我的初始工作被取消,这些副作用仍然存在。

即使刺激活动被取消或中止,副作用仍然存在。

示例 2:B 树分裂

数据库管理系统通常将记录存储在 B 树中。考虑以下场景

• 记录 X 由用户在面向记录的抽象层级作为事务 T1 的一部分插入。

• 数据库系统调用其 B 树管理器,该管理器向下遍历 B 树以插入记录 X。当发现 B 树的叶子太满而无法容纳记录 X 时,它将叶子分裂成两个并将记录 X 存储在其中一个中。

• 事务 T1 执行更多操作。

• 事务 T1 在面向记录的层级中止。因此,调用 B 树管理器以从 B 树中删除记录 X,它确实这样做了。B 树叶子的分裂并未撤消。

当事务 T1 中止时,T1 的所有影响都从构成数据库的记录集中消除。尽管如此,B 树的叶子已经被分裂并且仍然分裂。图 1 显示了分层抽象,数据库记录位于顶部,B 树实现位于底部。数据库事务插入到 B 树中,导致块分裂。稍后,数据库事务中止,导致从 B 树中删除。虽然记录 X 从 B 树中删除,但块分裂不一定会被撤消。

Side Effects, Front and Center!

面向记录的数据库在删除 T1 后是正确的。B 树作为 B 树,在具有正确的叶子、索引和指针的情况下是正确的。尽管如此,B 树是不同的,因为事务插入并在稍后删除了记录 X。

B 树的分裂是中止事务 T1 的副作用。从数据库中记录集的角度来看,那是 TMI。

幂等性和副作用

我个人认为,所有分布式计算都依赖于超时、重试和幂等性。3 幂等性是某些操作的属性,你可以多次执行这些操作,但获得的结果与执行一次相同。超时、重试和幂等性允许以非常高的成功概率分发工作。

现在,如果存在副作用,幂等性意味着什么?如果操作导致调用监控,那么该操作是幂等的吗?这将产生两条监控记录,因此,结果不是相同的。如果操作在期望的抽象层级是可重复的,则该操作是幂等的。如果日志记录和监控记录了两次尝试,通常认为是可以接受的。

幂等性由观察者决定!

幂等操作的副作用始终是可以接受的。毕竟,它们是副作用,因此,在语义上并不重要。

我会谈到滞后效应

系统的某一层级通常会缓慢地撤消它最近做的事情。这避免了整个系统过于激进地摇摆和抖动。

例如,当酒店预订因为我选择不去欧洲而被取消时,这可能不会改变杂货订单。也许我的预订将入住率推高到 200 间客房,并且对餐厅的需求达到了新的水平。最有可能的是,预计入住率需要降至 180 间左右,酒店才会调整杂货订单。反复致电杂货店安排,然后取消,然后再安排送货很可能会导致杂货店将你从客户列表中删除。

同样,大多数 B 树管理器并不急于在两个相邻块各自低于 50% 时合并它们。反复调整其内容的成本太高。

来自取消工作的副作用有时会使系统处于与之前不同的状态。反过来,这可能会影响后续请求。

结论

我们的系统以有趣的方式组合,并具有有趣的交互。为了应对这种情况,很多时候我们需要忽略我们使用的系统内部的复杂性,并假装生活比实际更简单。这很棒!我们生活在更高的抽象层级,并且不关注细节。

一个系统的副作用是另一个系统的命脉

尽管如此,提供较低抽象层级的系统将其工作视为其存在的原因。杂货订单是餐厅调度应用程序的主要目的。同样,B 树管理器必须保留记录,将它们放入 B 树中,并在必要时进行分裂。这不是副作用,而是工作的一部分。

副作用只是不关心自己事情的爱管闲事的人的副作用!

只需忽略 TMI!

如果每个系统都关注自己的抽象层级,而忽略其他抽象层级的 TMI,那么所有这些组合都是有意义的。良好的设计包括了解何时事物是相关的,何时事物是 TMI。毕竟,你叔公的消化问题与他的医生有关!


参考文献

1. Gray, J., Reuter, A. 1993. 分布式事务处理:概念和技术Morgan Kaufmann

2. Haerder, T., Reuter, A. 1983. 面向事务的数据库恢复原则。 计算调查 15(4): 287.

3. Helland, P. 2012. 幂等性不是一种疾病。acmqueue 10(4).

4. Weikum, G., Schek, H.-J. 1991. 多级事务和开放式嵌套事务。数据工程 14(1): 60-64.


相关文章

与 Erik Meijer 和 José Blakeley 的对话
微软对 ORM 的看法
https://queue.org.cn/detail.cfm?id=1394137

硬件系统设计中的抽象
- Rishiyur S. Nikhil, Bluespec Inc.
将软件语言的经验教训应用于使用 Bluespec SystemVerilog 的硬件语言
https://queue.org.cn/detail.cfm?id=2020861

弥合对象-关系鸿沟
- Craig Russell, Sun Microsystems
ORM 技术可以简化数据访问,但要注意引入这个新抽象层带来的挑战。
https://queue.org.cn/detail.cfm?id=1394139


Pat Helland 自 1978 年以来一直从事事务系统、数据库、应用程序平台、分布式系统、容错系统和消息传递系统的实施工作。为了消遣,他偶尔会撰写技术论文。他目前在 Salesforce 工作。

版权所有 © 2017 归所有者/作者所有。出版权已许可给 。

acmqueue

最初发表于 Queue 卷 15,第 2 期
数字图书馆 中评论本文





更多相关文章

Catherine Hayes, David Malone - 质疑非加密哈希函数的评估标准
虽然加密和非加密哈希函数无处不在,但它们的设计方式似乎存在差距。出于各种安全要求,存在许多加密哈希的标准,但在非加密方面,存在一定的民间传说,尽管哈希函数历史悠久,但尚未得到充分探索。虽然针对真实世界数据集的均匀分布很有意义,但当面对具有特定模式的数据集时,这可能是一个挑战。


Nicole Forsgren, Eirini Kalliamvakou, Abi Noda, Michaela Greiler, Brian Houck, Margaret-Anne Storey - DevEx 行动
随着领导者在财政紧缩和人工智能等变革性技术的背景下寻求优化软件交付,DevEx(开发者体验)在许多软件组织中越来越受到关注。技术领导者凭直觉接受,良好的开发者体验能够实现更有效的软件交付和开发者幸福感。然而,在许多组织中,改进 DevEx 的拟议举措和投资难以获得支持,因为业务利益相关者质疑改进的价值主张。


João Varajão, António Trigo, Miguel Almeida - 低代码开发生产力
本文旨在通过介绍使用基于代码、低代码和极端低代码技术进行的实验室实验结果来研究生产力差异,从而为该主题提供新的见解。低代码技术已清楚地显示出更高的生产力水平,为低代码在短期/中期内主导软件开发主流提供了强有力的论据。本文报告了程序和协议、结果、局限性和未来研究的机会。


Ivar Jacobson, Alistair Cockburn - 用例至关重要
虽然软件行业是一个快节奏且令人兴奋的世界,其中不断开发新的工具、技术和方法来服务于商业和社会,但它也很健忘。在快速前进的匆忙中,它容易受到时尚的摆布,并且可能会忘记或忽略针对其面临的一些永恒问题的经过验证的解决方案。用例于 1986 年首次引入,并在后来普及,就是这些经过验证的解决方案之一。





© 保留所有权利。

© . All rights reserved.