第 1 章:数据系统架构中的权衡
没有解决方案,只有权衡。……但你要努力争取你能得到的最佳权衡,而这就是你所能期望的一切。 —Thomas Sowell,Fred Barnes 访谈(2005 年)
如今,数据是许多应用开发的核心。随着 Web 和移动应用、软件即服务(SaaS)以及云服务的兴起,将来自许多不同用户的数据存储在共享的基于服务器的数据基础设施中已成为常态。来自用户活动、业务交易、设备和传感器的数据需要被存储,并可供分析。当用户与应用程序交互时,他们既读取已存储的数据,也会产生更多数据。
少量数据可以在单台机器上存储和处理,通常相当容易处理。然而,随着数据量或查询速率的增长,数据需要分布到多台机器上,这便引入了许多挑战。随着应用需求变得更加复杂,仅将一切存储在一个系统中已不再足够,可能需要结合多个提供不同能力的存储或处理系统。
我们将一个应用称为 数据密集型 应用,如果数据管理是该应用开发中的主要挑战之一 [1]。在计算密集型系统中,挑战在于并行化非常大的计算;而在数据密集型应用中,我们通常更关心诸如存储和处理大量数据、管理数据变更、确保在故障和并发情况下的一致性,以及确保服务的高可用性等问题。
这类应用通常由提供常用功能的标准构建模块搭建而成。例如,许多应用需要执行以下操作:
- 存储数据,以便它们或其他应用日后能再次找到(数据库)
- 记住昂贵操作的结果,以加速读取(缓存)
- 允许用户通过关键字搜索数据或以各种方式过滤数据(搜索索引)
- 在事件和数据变更发生时立即处理它们(流处理)
- 定期处理大量累积数据(批处理)
在构建应用时,我们通常会采用几个软件系统或服务(如数据库或 API),并通过应用代码将它们粘合在一起。如果您的需求恰好是这些数据系统设计之初所针对的,那么这个过程会相当简单。然而,随着应用变得越来越雄心勃勃,挑战也随之出现。有许多具有不同特性的数据库系统,适用于不同目的——您如何选择使用哪一个?有各种缓存方法、多种构建搜索索引的方式等等——您如何权衡它们各自的利弊?您需要找出哪些工具和方法最适合手头的任务,而当需要完成单个工具无法独立完成的工作时,组合工具可能会很困难。
本书是一本指南,旨在帮助您决定使用哪些技术以及如何组合它们。正如您将看到的,没有任何一种方法在根本上优于其他方法;一切都有其优缺点。通过本书,您将学会提出正确的问题来评估和比较数据系统,从而找出最适合您特定应用需求的方法。
我们将从审视如今数据在组织中通常如何使用开始我们的旅程。这里的许多思想源于企业软件(即大型组织(如大公司和政府)的软件需求和工程实践),因为历史上只有大型组织才拥有需要复杂技术解决方案的大量数据。如果您的数据量足够小,您可以直接将其保存在电子表格中!然而,最近,较小的公司和初创公司管理大量数据并构建数据密集型系统也变得很常见。
数据系统的一个关键挑战在于,不同的人需要对数据做截然不同的事情。如果您在一家公司工作,您和您的团队会有一套优先事项,而另一个团队可能有着完全不同的目标,即使你们可能处理的是相同的数据集!而且,这些目标可能没有被明确阐述,这可能导致对正确方法的误解和分歧。为了帮助您理解您的选择,本章比较了几个对比概念并探讨了它们的权衡。我们将考虑以下主题:
- 操作型系统与分析型系统的区别(第 3 页的“操作型系统与分析型系统”)
- 云服务与自托管系统的利弊(第 12 页的“云服务与自托管”)
- 何时从单节点系统转向分布式系统(第 19 页的“分布式系统与单节点系统”)
- 平衡业务需求与用户权利(第 24 页的“数据系统、法律与社会”)
本章还定义了您将在本书后续部分需要用到的术语。
术语:前端与后端
我们在本书中讨论的大部分内容都与后端开发相关。解释一下这个术语:对于 Web 应用,客户端代码(在 Web 浏览器中运行)称为前端,而处理用户请求的服务器端代码称为后端。移动应用与前端类似,它们提供用户界面,通常通过互联网与服务器端后端通信。前端有时会在用户设备上本地管理数据 [2],但最大的数据基础设施挑战通常在于后端:前端只需处理一个用户的数据,而后端则代表所有用户管理数据。
后端服务通常可通过 HTTP(有时是 WebSocket)访问;它通常包含应用代码,这些代码在一个或多个数据库中读写数据,有时还与其他数据系统(如缓存或消息队列,我们可统称为数据基础设施)交互。应用代码通常是无状态的(即,当它处理完一个 HTTP 请求后,它会忘记关于该请求的一切),任何需要在请求之间持久化的信息都必须存储在客户端或服务器端的数据基础设施中。
操作型系统与分析型系统
如果您在企业中从事数据系统工作,您很可能会遇到几种不同类型的数据处理人员。第一种是后端工程师,他们构建处理数据读写请求的服务;这些服务通常直接或间接(通过其他服务)服务外部用户(见第 21 页的“微服务与无服务器”)。有时服务是供组织内部其他部门使用的。
除了管理后端服务的团队,通常还有另外两组人员需要访问组织的数据:业务分析师,他们生成关于组织活动的报告,以帮助管理层做出更好的决策(商业智能,BI);以及数据科学家,他们寻找数据中的新颖见解,或者创建由数据分析和机器学习(ML)/AI 驱动的面向用户的产品功能(例如,电子商务网站上的“购买了 X 的人也购买了 Y”推荐、预测分析如风险评分或垃圾邮件过滤,以及搜索结果排序)。
尽管业务分析师和数据科学家倾向于使用不同的工具并以不同的方式工作,但他们有一些共同的做法。首先,两者都执行分析,这意味着他们查看用户和后端服务生成的数据。其次,他们通常不修改这些数据(可能除了修正错误外),尽管他们可能会创建衍生数据集,在其中原始数据以某种方式被处理过。
这导致了两种系统之间的分离——一个我们在本书中会一直使用的区分:
- 操作型系统由创建数据的后端服务和数据基础设施组成——例如,通过服务外部用户。在这里,应用代码基于用户执行的操作,既读取也修改其数据库中的数据。
- 分析型系统服务于业务分析师和数据科学家的需求。它们包含来自操作型系统的数据只读副本,并针对分析所需的数据处理类型进行了优化。
正如我们将在下一节中看到的,操作型系统和分析型系统通常出于充分的理由被保持分离。随着这些系统的成熟,出现了两个新的专业化角色:数据工程师和分析工程师。数据工程师是那些知道如何集成操作型系统和分析型系统,并对组织的数据基础设施承担更广泛责任的人 [3]。分析工程师对数据进行建模和转换,使其对组织中的业务分析师和数据科学家更有用 [4]。
许多工程师专门从事操作型或分析型方面的工作。然而,本书涵盖了操作型和分析型数据系统,因为两者在组织内数据的生命周期中都扮演着重要角色。我们将深入探讨用于向内部和外部用户提供服务的数据基础设施,以便您能更好地与这个分界线另一侧的同事合作。
表征事务处理与分析
在早期商业数据处理中,对数据库的一次写入通常对应一笔商业交易的发生:完成一笔销售、向供应商下订单、支付员工工资等。随着数据库扩展到不涉及金钱交易的领域,术语“事务”仍然被保留下来,指的是构成一个逻辑单元的一组读写操作。
关键术语:事务
一个事务是构成一个逻辑工作单元的一组读写操作。在操作型系统中,事务用于保证数据的一致性和完整性。
理解分离
操作型系统与分析型系统的分离并非偶然。操作型系统需要高并发、低延迟的读写操作以支持实时用户交互;而分析型系统则针对大量数据的扫描、聚合和复杂查询进行了优化。将两者分开可以避免分析工作负载影响关键的业务操作。
操作型与分析型系统
第8章将详细探讨事务的含义。本章松散地使用该术语,指代低延迟的读写操作。
尽管数据库开始被用于多种类型的数据——社交媒体上的帖子、游戏中的动作、通讯录中的联系人,以及许多其他数据——基本的访问模式仍然类似于处理业务事务。操作型系统通常通过键查找少量记录(这被称为点查询)。记录根据用户的输入进行插入、更新或删除。由于这些应用程序是交互式的,这种访问模式被称为在线事务处理(OLTP)。
然而,数据库也开始越来越多地用于分析,其访问模式与OLTP截然不同。通常,分析查询会扫描大量记录并计算聚合统计(如计数、总和或平均值),而不是将单个记录返回给用户。例如,某连锁超市的业务分析师可能希望回答如下分析查询:
- 我们每家门店1月份的总收入是多少?
- 最近一次促销活动中,香蕉的销量比平时多多少?
- 哪种品牌的婴儿食品最常与X品牌尿布一起购买?
这些类型的查询产生的报告对商业智能(BI)至关重要,帮助管理层决定下一步行动。为了将这种数据库使用模式与事务处理区分开来,它被称为在线分析处理(OLAP) [5]。OLTP与分析之间的区别并不总是泾渭分明,但表1-1列出了一些典型特征。
表1-1. 操作型系统与分析型系统的特征比较
| 属性 | 操作型系统(OLTP) | 分析型系统(OLAP) |
|---|---|---|
| 主要读取模式 | 点查询(按键获取单个记录) | 大量记录上的聚合 |
| 主要写入模式 | 创建、更新、删除单个记录 | 批量导入(ETL)或事件流 |
| 用户示例(人) | Web/移动应用终端用户 | 内部分析师,用于决策支持 |
| 用户示例(机器) | 检查操作是否被授权 | 检测欺诈/滥用模式 |
| 查询类型 | 固定的、由应用程序预定义 | 任意的、分析师临时探索 |
| 查询量 | 大量小查询 | 少量查询,每个查询复杂 |
| 数据表示 | 数据的最新状态(当前时间点) | 随时间发生的事件历史 |
| 数据集大小 | 数GB到数TB | 数TB到数PB |
OLAP中的"在线"一词含义并不明确;它可能表明查询不仅仅用于预定义报表,分析师还可以交互式地使用OLAP系统进行探索性查询。
在操作型系统中,用户通常不被允许编写自定义SQL查询并在数据库上运行,因为这可能使他们读取或修改无权访问的数据。他们还可能编写执行代价高昂的查询,从而影响其他用户的数据库性能。由于这些原因,OLTP系统主要运行固化在应用程序代码中的固定查询集合,仅偶尔使用一次性自定义查询进行维护或故障排除。另一方面,分析型数据库通常允许用户自由地手动编写任意SQL查询,或使用数据可视化或仪表板工具(如Tableau、Looker或Microsoft Power BI)自动生成查询。
还有一类系统专为分析工作负载(聚合大量记录的查询)设计,但嵌入到面向用户的产品中。这类用例被称为产品分析或实时分析,相关系统包括Pinot、Druid和ClickHouse [6]。这些系统实时摄入数据,并针对低延迟查询响应进行了优化。相比之下,传统的OLAP系统通常批量摄入数据,并针对高吞吐量查询处理进行优化。
数据仓库
最初,同一数据库既用于事务处理也用于分析查询。SQL在这方面表现出相当灵活性;它对两种查询都适用。然而,在20世纪80年代末和90年代初,出现了一种趋势:公司停止使用其OLTP系统进行分析,而是将分析运行在单独的数据库系统上。这个单独的数据库被称为数据仓库。
一家大型企业可能拥有数十甚至数百个OLTP系统:为面向客户的网站提供支持的系统、控制实体店销售点(结账)系统的系统、跟踪仓库库存的系统、规划车辆路线的系统、管理供应商的系统、管理员工的系统,以及执行许多其他任务的系统。每个系统都很复杂,需要一个团队来维护,因此它们最终基本上独立运行。
业务分析师和数据科学家通常不宜直接查询这些OLTP系统,原因如下:
- 感兴趣的数据可能分散在多个操作型系统中,导致难以在单个查询中合并这些数据集(这个问题称为数据孤岛)。
- 适合OLTP的模式和数据布局不太适合分析(参见第77页的”星型和雪花型:分析模式”)。
- 分析查询可能代价高昂,在OLTP数据库上运行会影响其他用户的性能。
- 出于安全或合规原因,OLTP系统可能位于不允许用户直接访问的单独网络中。
相比之下,数据仓库是一个单独的数据库,分析师可以随心所欲地查询它,而不会影响OLTP操作 [7]。正如我们在第4章中将看到的,数据仓库存储数据的方式通常与OLTP数据库有很大不同,以优化分析中常见的查询类型。
数据仓库包含公司所有各种OLTP系统中数据的只读副本。数据从OLTP数据库中提取(使用定期数据转储或连续更新流),转换为分析友好的模式,进行清理,然后加载到数据仓库中。将数据加载到数据仓库的过程称为提取-转换-加载(ETL),如图1-1所示。有时转换和加载步骤的顺序会互换(即转换在数据仓库中加载后进行),从而形成ELT。
图1-1展示了一个简化版本。在某些情况下,ETL过程的数据源是外部SaaS产品,例如客户关系管理(CRM)、电子邮件营销或信用卡处理系统。在这种情况下,你无法直接访问原始数据库,因为它只能通过软件供应商的API访问。将这些外部系统的数据导入你自己的数据仓库,可以实现SaaS API无法实现的分析。针对SaaS API的ETL通常由专业数据连接器服务(如Fivetran、Singer或Airbyte)实现。
一些数据库系统提供混合事务/分析处理(HTAP),旨在单个系统中支持OLTP和分析,而无需将数据从一套系统ETL到另一套系统 [8, 9]。然而,许多HTAP系统内部由一个OLTP系统与一个独立分析系统耦合而成,隐藏在通用接口后面——因此,理解这两种系统的区别对于理解它们的工作原理仍然至关重要。
此外,即使HTAP存在,由于事务型系统和分析型系统的目标和需求不同,通常仍将它们分离。特别是,良好的实践认为每个操作型系统都应有自己的数据库(参见第21页的”微服务与无服务器”),这可能导致数百个独立的操作型数据库;另一方面企业通常只有一个数据仓库,以便业务分析师能够在单个查询中组合来自多个操作系统的数据。
因此,HTAP 并不会取代数据仓库。相反,当同一个应用程序既需要执行扫描大量行的分析查询,又需要以低延迟读取和更新单个记录时,HTAP 十分有用。例如,欺诈检测就可能涉及此类工作负载 [10]。
操作型系统与分析型系统之间的分离是更广泛趋势的一部分。随着工作负载变得越来越苛刻,系统也变得更加专业化并针对特定工作负载进行了优化。通用系统可以轻松处理小数据量,但规模越大,系统就越倾向于专业化 [11]。
从数据仓库到数据湖
数据仓库通常使用通过 SQL 查询的关系数据模型(参见第 3 章),并可能借助专门的 BI 软件。这种模型适用于业务分析师需要的查询类型,但对于数据科学家执行以下任务的需求则不太适合:
- 将数据转换为适合训练机器学习模型的形式。这通常需要将数据库表的行和列转换为数值向量或矩阵,称为特征。以最大化训练模型性能的方式执行此转换的过程称为特征工程,通常需要难以用 SQL 表达的定制代码。
- 对文本数据(例如产品评论)使用自然语言处理(NLP)技术,试图从中提取结构化信息(例如作者的情绪或他们提到的主题)。类似地,数据科学家可能需要通过计算机视觉技术从照片中提取结构化信息。
尽管人们曾努力向 SQL 数据模型添加机器学习运算符 [12],并在关系型基础上构建高效的机器学习系统 [13],但许多数据科学家更倾向于不在关系数据库(如数据仓库)中工作。相反,许多人更喜欢使用 Python 数据分析库(如 Pandas 和 scikit-learn)、统计分析语言(如 R)以及分布式分析框架(如 Spark)[14]。我们将在第 105 页的“DataFrames、矩阵和数组”中进一步讨论这些内容。
因此,组织面临一种需求:以适合数据科学家使用的形式提供数据。答案是数据湖:一个集中式数据存储库,保存通过 ETL 流程从操作系统中获取的、可能对分析有用的任何数据的副本。与数据仓库不同的是,数据湖仅包含文件,不强制任何特定的文件格式、数据模型或模式 [15]。数据湖中的文件可能是数据库记录的集合,使用 Avro 或 Parquet 等文件格式编码(参见第 5 章),但数据湖同样可以包含文本、图像、视频、传感器读数、稀疏矩阵、特征向量、基因组序列或任何其他类型的数据 [16]。除了更加灵活之外,数据湖通常也比关系型数据存储更便宜,因为它可以使用商品化的文件存储,例如对象存储(参见第 14 页的“云原生系统架构”)。
ETL 流程已推广为数据管道,在某些情况下,数据湖已成为从操作系统到数据仓库路径上的中间站。数据湖包含操作系统生成的“原始”形式的数据,无需转换为关系型数据仓库模式。这种方法的好处是每个数据消费者都可以将原始数据转换为最适合其需求的形式。这有时被称为寿司原则:“生数据更好”[17]。
超越数据湖
随着分析实践的成熟,组织越来越关注分析系统和数据管道的管理与运营,例如在 DataOps 宣言 [18] 中所述。这在一定程度上是由治理、隐私和遵守法规(如通用数据保护条例 (GDPR) 和加州消费者隐私法案 (CCPA))的问题驱动的,我们将在第 24 页的“数据系统、法律与社会”以及第 14 章中讨论这些内容。
另一个重要因素是,用于分析的数据越来越多地不仅以文件和关系表的形式提供,还以事件流的形式提供(参见第 12 章)。对于基于文件的数据分析,您可以定期(例如每天)重新运行分析以响应数据的变化,但流处理使分析系统能够在秒级内更快地响应事件。根据应用及其时间敏感性的不同,流处理方法可能很有价值,例如用于识别和阻止潜在的欺诈或滥用活动。
在某些情况下,分析系统的输出会提供给操作系统(这个过程有时称为反向 ETL [19])。例如,在分析系统上训练的机器学习模型可能被部署到生产环境中,以便为最终用户生成推荐,例如“购买 X 的人还购买了 Y”。机器学习模型可以通过使用 TFX、Kubeflow 或 MLflow 等专用工具部署到操作系统中。
记录系统与衍生数据
与操作型系统和分析型系统之间的区分相关,本书还区分了记录系统和衍生数据系统。这些术语很有用,因为它们有助于澄清数据在系统中的流动:
记录系统 记录系统(也称为事实来源)保存数据的权威或规范版本。当新数据进入时(例如用户输入),它首先被写入这里。每个事实只表示一次(表示通常是规范化的;参见第 72 页的“规范化、反规范化和连接”)。如果另一个系统与记录系统之间存在任何差异,则记录系统中的值(按定义)是正确的。
衍生数据系统 衍生系统中的数据是获取另一个系统中的现有数据并以某种方式转换或处理的结果。如果您丢失了衍生数据,您可以从原始来源重新创建它。一个典型的例子是缓存:如果缓存中存在数据,则可以从缓存中提供数据;但如果缓存不包含您需要的内容,您可以回退到底层数据库。反规范化的值、索引、物化视图、转换后的数据表示以及基于数据集训练的模型也属于此类。
从技术上讲,衍生数据是冗余的,因为它复制了现有信息。然而,这些数据通常对于在读取查询上获得良好性能至关重要。您可以从单个源派生出多个数据集,从而能够从不同角度查看数据。
分析系统通常是衍生数据系统,因为它们是其他地方创建的数据的消费者。操作服务可能包含记录系统和衍生数据系统的混合。记录系统是首先写入数据的主要数据库,而衍生数据系统是加速常见读取操作的索引和缓存,特别是对于记录系统无法有效回答的查询。
大多数数据库、存储引擎和查询语言本身并非记录系统或衍生系统。数据库只是一种工具;如何使用由您决定。记录系统和衍生数据系统之间的区别不在于工具,而在于您在应用程序中使用它的方式。通过明确哪些数据是从哪些其他数据派生而来的,您可以为原本混乱的系统架构带来清晰度。
当一个系统中的数据是从另一个系统中的数据派生而来时,您需要一个流程,在记录系统中的原始数据发生变化时更新衍生数据。不幸的是,许多数据库的设计基于这样的假设:您的应用程序始终只需要使用那个数据库,并且它们不容易集成多个系统来传播此类更新。在第 11 章中,我们将讨论数据管道作为数据集成的方法,它使我们能够组合多个数据系统,以实现单个系统无法做到的事情。
至此,我们结束了分析型和事务处理的比较。在下一节中,我们将探讨您可能已经多次看到争论的另一个权衡。
云端与自托管
对于组织需要做的任何事情,首要问题之一是应该在内部完成还是外包。也就是说,应该构建还是购买?归根结底,这是一个关于业务优先级的问题。一个常见的经验法则是,属于组织核心竞争力或竞争优势的事情应该在内部完成,而非核心、常规或普通的事情应交由供应商处理 [20]。举一个极端的例子,大多数公司不会自己制造 CPU,因为从半导体制造商那里购买更便宜。
对于软件而言,需要做出的两个重要决定是:谁构建软件,以及谁部署软件。可能的范围如图 1-2 所示。一个极端是您自己编写并在内部运行的定制软件;另一个极端是广泛使用的云服务或 SaaS 产品,它们由外部供应商实施和运营,您仅通过 Web 界面或 API 访问。
图 1-2. 外包软件及其运营的决策谱系
中间地带是自托管或自行部署的现成软件(开源或商业软件)——例如,如果您下载 MySQL 并将其安装在您控制的服务器上。这可以是在您自己的硬件上(通常称为本地部署,即使服务器位于租用的数据中心机架中,而非字面上的您自己的场所),或者是在云中的虚拟机上(基础设施即服务,IaaS)。这个谱系上还有更多点,例如获取开源软件并运行其修改版本。
一个相关的问题是您如何部署服务——是在云端还是本地部署?——例如,是否使用 Kubernetes 之类的编排框架。然而,部署工具的选择超出了本书的范围,因为其他因素对数据系统的架构影响更大。
云服务的利弊
使用云服务,而不是自行运行同类软件,本质上是将该软件的运维工作外包给云提供商。对于这种方法,支持和反对的理由都很充分。云提供商声称,与自行搭建基础设施相比,使用他们的服务可以节省时间和金钱,并让你能够更快地推进工作。
然而,使用云服务是否真的比自托管更便宜、更简单,很大程度上取决于你的技能和系统的工作负载。如果你已经具备部署和运行所需系统的经验,并且你的负载非常可预测(即你需要的机器数量不会剧烈波动),那么通常自己购买机器并自行运行软件会更便宜 [21, 22]。
另一方面,如果你需要一个你尚不知道如何部署和运维的系统,那么采用云服务通常比学习如何管理该系统更容易、更快捷。专门招聘和培训人员来维护和运行系统可能会变得非常昂贵。即使在使用云服务时,你仍然需要一个运维团队(参见第17页的“云时代的运维”),但将基本的系统管理工作外包出去可以让你的团队腾出精力,专注于更高层级的问题。
将系统的运维工作外包给一家专门运行该系统的公司,可能会带来更好的服务,因为提供商从为众多客户提供服务中获得了运营专长。另一方面,如果你自己运行该服务,则可以针对你的特定工作负载进行配置和调优,使其表现良好。云服务不太可能愿意为你进行此类定制。
当你的系统负载随时间变化很大时,云服务尤其有价值。如果你配置的机器能够应对峰值负载,但这些计算资源在大部分时间里都处于闲置状态,那么系统的成本效益就会降低。在这种情况下,云服务的优势在于,它们可以让你更容易地根据需求变化来扩展或缩减计算资源。
例如,分析系统通常具有极其多变的负载。快速运行一个大型分析查询需要大量并行计算资源,但一旦查询完成,这些资源就会闲置,直到用户发出下一个查询。预定义的查询(例如用于每日报表的查询)可以被排队并调度以平滑负载,但对于交互式查询,你希望它们完成得越快,工作负载的变化就越大。如果你的数据集非常巨大,以至于快速查询需要大量计算资源,那么使用云可以节省资金,因为你可以将未使用的资源返还给提供商,而不是让它们闲置。对于较小的数据集,这种差异不那么明显。
自托管与云服务的权衡
- 成本:对于可预测的负载和有经验团队,自托管通常更便宜;对于波动负载或缺乏运维经验的情况,云服务更具成本效益。
- 控制力:自托管提供完全控制权,包括配置、调优和故障诊断;云服务则受限,可能面临供应商锁定、功能缺失、服务中断等风险。
- 运维负担:自托管需要自行维护基础设施;云服务将底层运维外包,但仍有高层运维责任。
云服务与自托管
云服务的最大缺点是你无法控制它:
- 如果它缺少你需要的功能,你所能做的就是礼貌地询问供应商是否愿意添加;你通常无法自己实现。
- 如果服务宕机,你只能等待它恢复。
- 如果你以触发bug或导致性能问题的方式使用该服务,诊断问题将很困难。对于你自己运行的软件,你可以从操作系统获取性能指标和调试信息来帮助理解其行为,并且可以查看服务器日志。而对于供应商托管的服务,你通常无法访问这些内部信息。
- 如果服务关闭、变得无法承受地昂贵,或者供应商以你不喜欢的方式改变其产品,你只能任其摆布;通常无法继续运行旧版本的软件,因此你将被强制迁移到替代服务 [23]。如果替代服务提供兼容的API,这种风险会降低,但对于许多云服务来说,并没有标准API,这提高了切换成本,使得供应商锁定成为一个问题。
- 如果云提供商位于另一个国家,并且该国与你所在的国家之间发生政治冲突,你可能因施加的制裁而被锁定无法使用该服务。
- 需要信任云提供商来保证数据安全,这可能会使遵守隐私和安全法规的过程复杂化。
尽管存在所有这些风险,越来越多的组织选择在云服务之上构建新应用程序,或者采用混合方法,将云服务用于系统的某些方面。然而,云服务不会取代所有内部数据系统。许多较老的系统早于云的出现,并且对于任何具有现有云服务无法满足的特定需求的服务,内部系统仍然是必要的。例如,高频交易等对延迟极其敏感的应用需要对硬件进行完全控制。
云原生系统架构
除了不同的经济模式(订阅服务,而不是购买硬件并授权软件在其上运行)之外,云的兴起也对数据系统的技术实现方式产生了深远的影响。术语“云原生”用于描述一种旨在利用云服务的架构。
原则上,几乎任何你可以自托管的软件也可以作为云服务提供,事实上,现在许多流行的数据系统都有这种托管服务。然而,从头开始设计为云原生的系统已被证明具有多项优势:在相同硬件上性能更好、故障恢复更快、能够快速扩展计算资源以匹配负载,以及支持更大的数据集 [24, 25, 26]。表1-2列出了这两类系统的一些示例。
表1-2. 自托管与云原生数据库系统示例
| 类别 | 自托管系统 | 云原生系统 |
|---|---|---|
| 操作型/OLTP | MySQL, PostgreSQL, MongoDB | AWS Aurora [24], Azure SQL DB Hyperscale [25], Google Cloud Spanner |
| 分析型/OLAP | Teradata, ClickHouse, Spark | Snowflake [26], Google BigQuery, Azure Synapse Analytics |
云服务的分层
许多自托管数据系统具有简单的系统需求;它们运行在常规操作系统上(如Linux或Windows),将数据作为文件存储在文件系统中,并通过标准网络协议(如TCP/IP)进行通信。少数系统依赖特殊硬件,如GPU(用于机器学习)或远程直接内存访问(RDMA)网络接口,但总体而言,自托管软件倾向于使用通用的计算资源:CPU、RAM、文件系统和IP网络。
在云中,这类软件可以在IaaS环境中运行,使用一个或多个具有特定CPU、内存、磁盘和网络带宽分配的VM(或实例)。与物理机器相比,云实例可以更快地配置,并且有更多种规格,但除此以外它们与传统计算机类似:你可以在其上运行任何你喜欢的软件,但需要自己负责管理。
相反,云原生服务的关键思想不仅是使用操作系统管理的计算资源,还要在更底层的云服务之上构建更高级别的服务。例如:
- 对象存储服务,例如Amazon S3、Azure Blob Storage和Cloudflare R2,用于存储大型文件。它们提供的API比典型文件系统更有限(基本的文件读写),但它们的优势在于隐藏了底层物理机器;该服务自动将数据分布到多台机器上,这样你就不必担心任何一台机器的磁盘空间耗尽。即使某些机器或其磁盘完全故障,也不会丢失数据。
- 许多其他服务又建立在对象存储和其他云服务之上。例如,Snowflake是一个基于云的分析型数据库(数据仓库),它依赖S3进行数据存储 [26],而其他一些服务又建立在Snowflake之上。
与计算中的抽象一样,对于应该使用什么,没有唯一的正确答案。通常,越高级的抽象往往越面向特定的用例。如果你的需求与更高级别系统设计所针对的情况相匹配,那么使用现有的更高级别系统很可能比你自己从较低级别系统构建它要省事得多。另一方面,如果没有高级别系统能满足你的需求,那么从较低级别组件自行构建是唯一的选择。
存储与计算分离
在传统计算中,磁盘存储被认为是持久的(我们假设一旦内容写入磁盘,就不会丢失)。为了容忍单个硬盘的故障,通常使用RAID(独立磁盘冗余阵列)在连接到同一台机器的多个磁盘上维护数据副本。RAID可以在硬件中实现,也可以在操作系统的软件中实现,并且对访问文件系统的应用程序是透明的。
在云中,计算实例(VM)也可能有本地磁盘,但云原生系统通常将这些磁盘更多地视为临时缓存,而不是长期存储。这是因为如果相关实例发生故障,或者为了适应负载变化而将实例替换为更大或更小的实例(在另一台物理机器上),本地磁盘将变得不可访问。
作为本地磁盘的替代方案,云服务还提供虚拟磁盘存储,可以从一个实例分离并附加到另一个实例(例如Amazon EBS、Azure托管磁盘和Google Cloud中的持久磁盘)。这种虚拟磁盘不是物理磁盘,而是一种云服务,由一组独立的机器提供,这些机器模拟磁盘的行为(一种块设备,每个块通常为4 KiB大小)。这项技术使得在云中运行传统的基于磁盘的软件成为可能,但块设备模拟引入了开销,而从头为云设计的系统可以避免这些开销 [24]。虚拟磁盘的使用也使应用程序对网络故障非常敏感,因为虚拟块设备上的每个I/O操作都是一次网络调用 [27]。
为了解决这个问题,云原生服务通常避免使用虚拟磁盘,而是构建在针对特定工作负载优化的专用存储服务之上。诸如S3之类的对象存储服务专为长期存储相当大(从几百KB到几GB)的文件而设计。数据库中的单个行或值通常比这小得多;因此,云数据库通常在一个单独的服务中管理较小的值,并将较大的数据块(包含多个单独的值)存储在对象存储中 [25, 28]。我们将在第4章中看到实现这一点的方法。
在传统的系统架构中,同一台计算机同时负责存储(磁盘)和计算(CPU和RAM),但在云原生系统中,这两项职责已经在一定程度上分离或解耦[9, 26, 29, 30]:例如,S3只存储文件,要分析这些数据,你需要在S3之外的其他地方运行分析代码。这意味着数据需要通过网络传输,我们将在第19页的“分布式系统与单节点系统”中进一步讨论。
此外,云原生系统通常是多租户的,这意味着每个客户不是拥有独立的机器,而是多个客户的数据和计算由同一服务在同一共享硬件上处理[31]。多租户可以实现更好的硬件利用率,更易于扩展和云提供商的管理,但它也需要精心的工程设计,以确保一个客户的活动不会影响其他客户系统的性能或安全[32]。
云计算时代的运维
传统上,管理组织服务端数据基础设施的人员被称为数据库管理员(DBA)或系统管理员(sysadmin)。最近,许多组织尝试将软件开发和运维的角色整合到团队中,使团队对后端服务和数据基础设施共同负责;DevOps理念推动了这一趋势。站点可靠性工程师(SRE)是Google对此理念的实现[33]。
运维的角色是确保向用户可靠地交付服务(包括配置基础设施和部署应用程序),并确保生产环境的稳定(包括监控和诊断可能影响可靠性的任何问题)。对于自托管系统,运维传统上涉及大量在单机层面的工作,例如容量规划(如监控可用磁盘空间并在空间耗尽前添加更多磁盘)、配置新机器、将服务从一台机器迁移到另一台、安装操作系统补丁。
许多云服务提供的API隐藏了实现该服务的底层机器。例如,云存储用按量计费取代了固定大小的磁盘,你可以无需事先规划容量需求就存储数据,然后根据使用的空间付费。此外,即使底层机器发生故障,许多云服务依然保持高可用(参见第43页的“可靠性与容错”)。
这种从关注单机到关注服务的转变伴随着运维角色的变化。提供可靠服务的高层目标保持不变,但流程和工具已经演变。
云与自托管
DevOps/SRE理念更强调以下几点:
- 设置自动化,偏好可重复的流程而非手动的一次性工作
- 使用临时虚拟机和服务,而非长期运行的服务器
- 支持频繁的应用更新
- 从事故中学习
- 保留组织关于系统的知识,即使人员流动[34]
随着云服务的兴起,角色出现了分化。基础设施公司的运维团队专注于为大量客户提供可靠服务的细节,而服务的客户则在基础设施上投入尽可能少的时间和精力[35]。
云服务的客户仍然需要运维,但他们关注的方面不同,例如为给定任务选择最合适的服务、集成服务、从一种服务迁移到另一种。即使按量计费消除了传统意义上的容量规划需求,仍然需要知道你在哪些用途上使用了哪些资源,以避免在不需要的云资源上浪费资金。容量规划变成了财务规划,性能优化变成了成本优化[36]。此外,云服务确实有资源限制或配额(例如可以同时运行的最大进程数),你需要在遇到它们之前了解并规划好[37]。
采用云服务可能比配置和运行自己的基础设施更容易、更快速,尽管你仍然需要学习如何使用云服务并可能绕开其限制。随着越来越多的供应商提供越来越广泛的云服务,针对不同用例,服务之间的集成成为一项特别的挑战[38, 39]。ETL(参见第7页的“数据仓库”)只是故事的一部分;运营型云服务也需要相互集成。目前,我们缺乏促进这种集成的标准,因此通常需要大量的手动工作。
其他不能完全外包给云服务的运维方面包括:维护应用程序及其所用库的安全性、管理自有服务之间的交互、监控服务负载、排查性能下降或中断等问题的根源。虽然云正在改变运维的角色,但对运维的需求一如既往。
分布式系统与单节点系统
涉及多台机器通过网络通信的系统称为分布式系统。参与分布式系统的每个进程称为一个节点。你可能出于以下原因希望使用这种系统:
固有分布 如果应用程序涉及两个或多个交互的用户,每个用户使用自己的设备,那么系统就不可避免地是分布式的:设备之间的通信必须通过网络进行。
云服务之间的请求 如果数据存储在一个服务中但在另一个服务中处理,这些数据必须通过网络从一个服务传输到另一个。因此,云原生系统和微服务(参见第21页的“微服务与无服务器”)是分布式的。
容错/高可用 如果你的应用程序需要在某台机器(或多台机器、网络、整个数据中心)宕机时继续工作,你可以使用多台机器提供冗余。当一台机器故障时,另一台可以接管。参见第43页的“可靠性与容错”和第6章。
可扩展性 如果数据量或计算需求超过单台机器的处理能力,你可以将负载分散到多台机器上。参见第49页的“可扩展性”。
延迟 如果你的用户遍布全球,你可能希望在世界各地的不同区域部署服务器,以便每个用户可以从地理上接近的服务器获得服务。这避免了用户等待网络数据包绕地球半圈来响应其请求。参见第37页的“描述性能”。
弹性 如果你的应用程序有时繁忙有时空闲,云部署可以按需扩展或收缩,以便只为当前使用的资源付费。这在单台机器上更难实现,因为单机需要配置为处理最大负载,即使在负载很低的时段。
专用硬件 系统的不同部分可以利用不同类型的硬件来匹配其工作负载。例如,对象存储可能使用多磁盘但少CPU的机器,数据分析系统可能使用多CPU、大内存但无磁盘的机器,机器学习系统可能使用带有GPU的机器(对于训练深度神经网络和其他ML任务,GPU比CPU高效得多)。
法律合规 一些国家有数据驻留法律,要求其管辖区域内人员的数据必须在地理上存储和处理在该国境内[40]。这些规则的适用范范围各不相同——例如,在某些情况下仅适用于医疗或金融数据,而在其他情况下则更广泛。因此,拥有多个此类司法管辖区用户的服务必须将其数据分布在多个位置的服务器上。
可持续性 如果你在何时何地运行作业方面有灵活性,你或许可以在可再生能源充足的时间和地点运行它们,并避免在电网紧张时运行。这可以减少碳排放,并利用廉价电力[41, 42]。
这些原因既适用于你自己编写的服务(应用程序代码),也适用于由现成软件(如数据库)组成的服务。
分布式系统的问题
分布式系统也有缺点。每个穿越网络的请求和API调用都需要处理失败的可能性。网络可能中断,服务可能过载或崩溃,因此任何请求都可能超时而无响应。这种情况下,我们不知道服务是否收到了请求,简单地重试可能不安全。我们将在第9章详细讨论这些问题。
尽管数据中心网络速度很快,但调用另一个服务仍然比在同一个进程中调用函数慢得多[43]。在处理大量数据时,将计算带到已经拥有数据的机器上比将数据从存储传输到另一台处理机器更快[44]。更多的节点并不总是更快;在某些情况下,一台计算机上的简单单线程程序可能比拥有超过100个CPU核心的集群表现更好[45]。
排查分布式系统的问题通常很困难——如果系统响应缓慢,如何确定问题出在哪里?在可观测性的标题下开发了诊断分布式系统问题的技术[46, 47],这涉及收集系统执行的数据,并允许以能够分析高级指标和单个事件的方式查询这些数据。诸如OpenTelemetry、Zipkin和Jaeger等跟踪工具允许你跟踪哪个客户端调用哪个服务器执行哪个操作,以及每次调用耗时多久[48]。
数据库提供了多种机制来确保数据一致性,我们将在第6章和第8章中看到。然而,当每个服务都有自己的数据库时,维护不同服务之间的数据一致性就成了应用程序的问题。我们在第8章中探讨的分布式事务是一种可能的确保一致性的技术,但在微服务环境中很少使用,因为它们违背了使服务彼此独立的目标,而且许多数据库并不支持它们[49]。
出于所有这些原因,在单台机器上执行任务通常比搭建分布式系统更简单、成本更低[22, 45, 50]。CPU、内存和磁盘变得更大、更快、更可靠。结合DuckDB、SQLite和KùzuDB等单节点数据库,许多工作负载现在可以在单节点上运行。我们将在第4章进一步探讨这个主题。
微服务与无服务器
将系统分布到多台机器上最常见的方法是将其划分为客户端和服务器,并让客户端向服务器发出请求。最常用的通信方式是HTTP,我们将在第180页的“通过服务的数据流:REST与RPC”中讨论。同一个进程既可以是服务器(处理传入请求),也可以是客户端(向其他服务发出出站请求)。
这种构建应用程序的方式传统上被称为服务导向架构(SOA);最近,这一思想被精炼为微服务架构[51, 52]。在微服务架构中,一个服务具有一个明确定义的用途(例如,在S3的情况下是文件存储);每个服务公开一个API,客户端可以通过网络调用它;每个服务由一个团队负责维护。一个复杂的应用程序因此可以被分解为多个相互交互的服务,每个服务由独立的团队管理。云原生系统大量使用服务分解,但本地部署系统也可以采用服务导向的方式。
将复杂的软件划分为多个服务有几个优点:
- 每个服务可以独立更新,减少团队之间的协调工作;
- 每个服务可以分配所需的硬件资源;
- 通过API隐藏实现细节,服务所有者可以自由更改实现而不影响客户端。
在数据存储方面,每个服务通常拥有自己的数据库,并且不在服务之间共享数据库。共享数据库实际上会使整个数据库结构成为服务API的一部分,从而使该结构难以更改。共享数据库还可能导致一个服务的查询对另一个服务的性能产生负面影响。
WARNING
另一方面,拥有多个服务本身也会滋生复杂性。在开发过程中测试服务可能很复杂,因为你还需要运行它所依赖的所有其他服务。而且,每个服务都需要基础设施来部署新版本、根据负载调整分配的硬件资源、收集日志、监控服务健康状况以及在出现问题时提醒轮值工程师。像Kubernetes这样的编排框架已成为部署服务的流行方式,因为它们为这些基础设施提供了基础。
此外,微服务API的演化可能具有挑战性。调用API的客户端期望它具有某些字段。开发人员可能希望根据业务需求的变化添加或删除API中的字段,但这可能会导致客户端失败。更糟糕的是,这种失败通常要到开发周期后期,当更新后的服务API部署到暂存或生产环境时才会被发现。像OpenAPI和gRPC这样的API描述标准有助于管理客户端和服务器API之间的关系;我们将在第5章进一步讨论。
微服务主要是一个针对人员问题的技术解决方案:允许不同团队独立推进,无需相互协调。这在大型公司中很有价值,但在团队较少的小公司中,使用微服务很可能是不必要的开销,最好以尽可能简单的方式实现应用程序[51]。
无服务器,或称函数即服务(FaaS),是另一种部署服务的方法,其中基础设施的管理被外包给云供应商[32]。使用虚拟机时,你必须明确选择何时启动或关闭实例;相比之下,在无服务器模型中,云提供商根据发往服务[53]的传入请求自动按需分配和释放硬件资源。就像云存储用按量计费模式取代了容量规划(提前决定购买多少磁盘)一样,无服务器方法将按量计费带到了代码执行中:你只为应用程序代码运行的时间付费,而无需预先配置资源。
为了提供这些好处,许多无服务器基础设施提供者对函数执行施加了时间限制并限制了运行时环境,并且服务在首次调用函数时可能遭受启动缓慢的问题。“无服务器”这个术语也可能产生误导;每次无服务器函数执行仍然运行在服务器上,但后续执行可能运行在不同的服务器上。此外,像BigQuery和各种Kafka服务等基础设施服务已经采用了“无服务器”术语,以表明它们的服务可以自动伸缩,并且它们按使用量而不是机器实例计费。
云计算与超级计算
云计算并不是构建大规模计算系统的唯一方式;另一种选择是高性能计算(HPC),也称为超级计算。尽管存在重叠,但HPC通常具有不同的优先级,并使用与云计算和企业数据中心系统不同的技术。以下是一些主要区别:
- 超级计算机通常用于计算密集型科学计算任务,如天气预报、气候建模、分子动力学(模拟原子和分子的运动)、复杂优化问题以及求解偏微分方程。另一方面,云计算往往用于在线服务、业务数据系统以及需要高可用性为用户请求提供服务的类似系统。
- 超级计算机通常运行大型批处理作业,这些作业会定期将计算状态检查点到磁盘。如果某个节点发生故障,常见的解决方案是简单地停止整个集群工作负载,修复故障节点,然后从最后一个检查点重新开始计算[54, 55]。对于云服务,停止整个集群通常是不可取的,因为服务需要持续为用户服务,并尽量减少中断。
- 超级计算机节点通常通过共享内存和RDMA进行通信,这些技术支持高带宽和低延迟,但假设系统用户之间有高度的信任[56]。在云计算中,网络和机器通常由互不信任的组织共享,需要更强的安全机制,例如资源隔离(如虚拟机)、加密和认证。
- 云数据中心网络通常基于IP和以太网,采用Clos拓扑结构以提供高二分带宽——这是衡量网络整体性能的常用指标[54, 57]。超级计算机通常使用专门的网络拓扑,例如多维网格和环形[58],对于具有已知通信模式的HPC工作负载,这些拓扑能产生更好的性能。
- 云计算允许将节点分布在多个地理区域,而超级计算机通常假定其所有节点都靠近在一起。
大规模分析系统有时与超级计算共享一些特征,这就是为什么如果你在这个领域工作,了解这些技术是值得的。然而,本书主要关注需要持续可用的服务,如第43页的“可靠性与容错”中所述。
数据系统、法律与社会
正如你在本章中所看到的,数据系统的架构不仅受到技术目标和需求的影响,还受到它们所支持组织的人员需求的影响。越来越多地,数据系统工程师意识到仅满足自己业务的需求是不够的;我们对整个社会也负有责任。
一个特别值得关注的问题是存储有关人员及其行为数据的系统。自2018年以来,GDPR赋予了多个欧洲国家居民对其个人数据更大的控制权和合法权利,世界各地的其他国家和州也采用了类似的隐私法规(例如,包括CCPA)。围绕AI的法规,如EU AI Act,对个人数据的使用施加了进一步的限制。
此外,即使在不受直接监管的领域,人们也越来越认识到计算机系统对人和社会的各种影响。社交媒体改变了个人消费新闻的方式,影响他们的政治观点,并可能影响选举结果。自动化系统越来越多地做出对个人具有深远影响的决策,例如谁应该获得贷款或保险、谁应该被邀请参加工作面试,或者谁应该被怀疑犯罪[59]。
每个从事此类系统工作的人都共同负有责任,要考虑其决策的道德影响,并确保其符合相关法律。并非每个人都需要成为法律和道德专家,但对法律和道德原则的基本意识与分布式系统的一些基础知识同样重要。
法律考虑因素正在影响数据系统设计的根本基础[60]。例如,GDPR赋予个人要求删除其数据的权利(有时称为被遗忘权)。然而,正如我们将在本书中看到的,许多数据系统依赖于不可变结构(如仅追加日志)作为其设计的一部分。我们如何确保删除位于本应为不可变的文件中间的一些数据?我们如何处理已并入派生数据集(见第10页的“记录系统与派生数据”)的数据删除,例如ML模型的训练数据?回答这些问题带来了新的工程挑战。
目前,我们还没有明确的指导方针,说明哪些特定技术或系统架构应被视为符合GDPR。该法规故意不强制要求特定的技术,因为这些技术可能随着技术的进步而迅速变化。相反,法律文本规定了宏观原则,这些原则有待解释。因此,如何遵守隐私法规没有简单的答案,但我们将通过这个视角来看待一些技术。
一般而言,我们存储数据是因为认为其价值大于存储成本。然而,值得记住的是,存储成本不仅限于你为S3或其他服务支付的账单。成本效益计算还应考虑数据泄露或被对手攻击所带来的责任风险和声誉损失风险,以及存储和处理未符合法律要求时可能产生的法律费用和罚款[50]。政府或警察机构也可能迫使公司交出数据。
当数据可能揭露被刑事定罪的行为时(例如,中东和非洲多个国家的同性恋行为,或美国多个州的堕胎行为),存储这些数据会为用户带来实际的安全风险。例如,前往堕胎诊所的行为可能轻易通过位置数据暴露,甚至可能通过用户随时间变化的IP地址日志(指示大致位置)暴露。
一旦考虑了所有风险,合理的选择可能是决定某些数据根本不值得存储,因此应将其删除。这一数据最小化原则(有时用德语术语 Datensparsamkeit 表示)与“大数据”哲学背道而驰,后者主张投机性地存储大量数据,以备将来可能有用[61]。但数据最小化原则符合GDPR,该法规规定个人数据只能出于特定、明确的目的收集;后续不得用于任何其他目的;且不得保留超过为实现收集目的所需的时间[62]。
企业也已注意到隐私和安全问题。信用卡公司要求支付处理业务遵守严格的支付卡行业(PCI)标准。处理方需接受独立审计方的定期评估,以验证持续合规性。软件供应商也面临越来越多的审查。许多买家现在要求其供应商遵守服务组织控制(SOC)2型标准。与PCI合规类似,供应商需接受第三方审计以验证遵守情况。
总体而言,平衡业务需求与被收集和处理数据的用户需求至关重要。这个话题远不止于此;在第14章中,我们将深入探讨伦理和法律合规问题,包括偏见和歧视问题。
总结
本章的主题是理解权衡——即认识到许多问题并非只有一个正确答案,而是有多种可能性,各有利弊。我们探讨了影响数据系统架构的一些最重要选择,并介绍了将在本书其余部分使用的术语。
我们从区分操作型系统(事务处理,OLTP)和分析型系统(OLAP)开始,探讨了它们的不同之处,不仅在于管理不同类型的数据和访问模式,还在于服务不同的受众。在此过程中,我们遇到了数据仓库和数据湖的概念,它们通过ETL接收来自操作系统的数据馈送。在第4章中,我们将看到操作型和分析型系统通常使用非常不同的内部数据布局,因为需要满足不同类型的查询。
然后,我们将云服务(相对较新的发展)与传统范式(此前主导数据系统架构的自托管软件)进行了比较。哪种方法更具成本效益在很大程度上取决于你的具体情况,但不可否认的是,云原生方法正在给数据系统的架构方式带来巨大变化——例如,在分离存储和计算的方式上。
云系统本质上是分布式的,我们简要考察了分布式系统与使用单台机器相比的一些权衡。在某些情况下,你无法避免使用分布式系统,但建议在可能将系统保持在单台机器上时,不要急于将其分布式化。在第9章中,我们将更详细地介绍分布式系统面临的挑战。
最后,我们看到数据系统的架构不仅取决于部署该系统的业务需求,还取决于保护被处理数据用户权利的隐私法规——这是许多工程师容易忽视的一个方面。如何将法律要求转化为技术实现尚未形式化,但在阅读本书其余部分时,牢记这个问题非常重要。
参考文献
[1] Richard T. Kouzes, Gordon A. Anderson, Stephen T. Elbert, Ian Gorton, and Deborah K. Gracio. “The Changing Paradigm of Data-Intensive Computing.” IEEE Computer, volume 42, issue 1, pages 26–34, January 2009. doi:10.1109/MC.2009.26
[2] Martin Kleppmann, Adam Wiggins, Peter van Hardenberg, and Mark McGranaghan. “Local-First Software: You Own Your Data, in Spite of the Cloud.” At 2019 ACM SIGPLAN International Symposium on New Ideas, New Paradigms, and Reflections on Programming and Software (Onward!), October 2019. doi:10.1145/3359591.3359737
[3] Joe Reis and Matt Housley. Fundamentals of Data Engineering. O’Reilly Media, 2022. ISBN: 9781098108304
[4] Rui Pedro Machado and Helder Russa. Analytics Engineering with SQL and dbt. O’Reilly Media, 2023. ISBN: 9781098142384
[5] Edgar F. Codd, S. B. Codd, and C. T. Salley. “Providing OLAP to User-Analysts: An IT Mandate.” E. F. Codd Associates, 1993. Archived at perma.cc/RKX8-2GEE
[6] Chinmay Soman and Neha Pawar. “Comparing Three Real-Time OLAP Databases: Apache Pinot, Apache Druid, and ClickHouse.” startree.ai, April 2023. Archived at perma.cc/8BZP-VWPA
[7] Surajit Chaudhuri and Umeshwar Dayal. “An Overview of Data Warehousing and OLAP Technology.” ACM SIGMOD Record, volume 26, issue 1, pages 65–74, March 1997. doi:10.1145/248603.248616
[8] Fatma Özcan, Yuanyuan Tian, and Pinar Tözün. “Hybrid Transactional/Analytical Processing: A Survey.” At ACM International Conference on Management of Data (SIGMOD), May 2017. doi:10.1145/3035918.3054784
[9] Adam Prout, Szu-Po Wang, Joseph Victor, Zhou Sun, Yongzhu Li, Jack Chen, Evan Bergeron, Eric Hanson, Robert Walzer, Rodrigo Gomes, and Nikita Shamgunov. “Cloud-Native Transactions and Analytics in SingleStore.” At International Conference on Management of Data (SIGMOD), June 2022. doi:10.1145/3514221.3526055
[10] Chao Zhang, Guoliang Li, Jintao Zhang, Xinning Zhang, and Jianhua Feng. “HTAP Databases: A Survey.” IEEE Transactions on Knowledge and Data Engineering, volume 36, issue 11, pages 6410–6429, April 2024. doi:10.1109/TKDE.2024.3389693
[11] Michael Stonebraker and Uğur Çetintemel. “‘One Size Fits All’: An Idea Whose Time Has Come and Gone.” At 21st International Conference on Data Engineering (ICDE), April 2005. doi:10.1109/ICDE.2005.1
[12] Jeffrey Cohen, Brian Dolan, Mark Dunlap, Joseph M. Hellerstein, and Caleb Welton. “MAD Skills: New Analysis Practices for Big Data.” Proceedings of the VLDB Endowment, volume 2, issue 2, pages 1481–1492, August 2009. doi:10.14778/1687553.1687576
[13] Dan Olteanu. “The Relational Data Borg Is Learning.” Proceedings of the VLDB Endowment, volume 13, issue 12, pages 3502–3515, August 2020. doi:10.14778/3415478.3415572
[14] Matt Bornstein, Martin Casado, and Jennifer Li. “Emerging Architectures for Modern Data Infrastructure: 2020.” future.a16z.com, October 2020. Archived at perma.cc/LF8W-KDCC
[15] Rihan Hai, Christos Koutras, Christoph Quix, and Matthias Jarke. “Data Lakes: A Survey of Functions and Systems.” IEEE Transactions on Knowledge and Data Engineering (TKDE), volume 35, issue 12, pages 12571–12590, December 2023. doi:10.1109/TKDE.2023.3270101
[16] Martin Fowler. “Data Lake.” martinfowler.com, February 2015. Archived at perma.cc/4WKN-CZUK
[17] Bobby Johnson and Joseph Adler. “The Sushi Principle: Raw Data Is Better.” At Strata+Hadoop World, February 2015.
[18] DataKitchen, Inc. “The DataOps Manifesto.” dataopsmanifesto.org, 2017. Archived at perma.cc/3F5N-FUQ4
[19] Tejas Manohar. “What Is Reverse ETL: A Definition & Why It’s Taking Off.” hightouch.io, November 2021. Archived at perma.cc/A7TN-GLYJ
[20] Camille Fournier. “Why Is It So Hard to Decide to Buy?” skamille.medium.com, July 2021. Archived at perma.cc/6VSG-HQ5X
[21] David Heinemeier Hansson. “Why We’re Leaving the Cloud.” world.hey.com, October 2022. Archived at perma.cc/82E6-UJ65
[22] Nima Badizadegan. “Use One Big Server.” specbranch.com, August 2022. Archived at perma.cc/M8NB-95UK
[23] Steve Yegge. “Dear Google Cloud: Your Deprecation Policy Is Killing You.” steve-yegge.medium.com, August 2020. Archived at perma.cc/KQP9-SPGU
[24] Alexandre Verbitski, Anurag Gupta, Debanjan Saha, Murali Brahmadesam, Kamal Gupta, Raman Mittal, Sailesh Krishnamurthy, Sandor Maurice, Tengiz Kharatishvili, and Xiaofeng Bao. “Amazon Aurora: Design Considerations for High Throughput Cloud-Native Relational Databases.” At ACM International Conference on Management of Data (SIGMOD), May 2017. doi:10.1145/3035918.3056101
[25] Panagiotis Antonopoulos, Alex Budovski, Cristian Diaconu, Alejandro Hernandez Saenz, Jack Hu, Hanuma Kodavalla, Donald Kossmann, Sandeep Lingam, Umar Farooq Minhas, Naveen Prakash, Vijendra Purohit, Hugh Qu, Chaitanya Sreenivas Ravella, Krystyna Reisteter, Sheetal Shrotri, Dixin Tang, and Vikram Wakade. “Socrates: The New SQL Server in the Cloud.” At ACM International Conference on Management of Data (SIGMOD), June 2019. doi:10.1145/3299869.3314047
[26] Midhul Vuppalapati, Justin Miron, Rachit Agarwal, Dan Truong, Ashish Motivala, and Thierry Cruanes. “Building an Elastic Query Engine on Disaggregated Storage.” At 17th USENIX Symposium on Networked Systems Design and Implementation (NSDI), February 2020.
[27] Nick Van Wiggeren. “The Real Failure Rate of EBS.” planetscale.com, March 2025. Archived at perma.cc/43CR-SAH5
[28] Colin Breck. “Predicting the Future of Distributed Systems.” blog.colinbreck.com, August 2024. Archived at perma.cc/K5FC-4XX2
[29] Gwen Shapira. “Compute-Storage Separation Explained.” thenile.dev, January 2023. Archived at perma.cc/QCV3-XJZZ
[30] Ravi Murthy 和 Gurmeet Goindi. “AlloyDB for PostgreSQL Under the Hood: Intelligent, Database-Aware Storage.” cloud.google.com, 2022年5月. 存档于 archive.org
[31] Jack Vanlightly. “The Architecture of Serverless Data Systems.” jack-vanlightly.com, 2023年11月. 存档于 perma.cc/UDV4-TNJ5
[32] Eric Jonas, Johann Schleier-Smith, Vikram Sreekanti, Chia-Che Tsai, Anurag Khandelwal, Qifan Pu, Vaishaal Shankar, Joao Carreira, Karl Krauth, Neeraja Yadavadkar, Joseph E. Gonzalez, Raluca Ada Popa, Ion Stoica, 和 David A. Patterson. “Cloud Programming Simplified: A Berkeley View on Serverless Computing.” arXiv:1902.03383, 2019年2月.
[33] Betsy Beyer, Jennifer Petoff, Chris Jones, 和 Niall Richard Murphy. Site Reliability Engineering: How Google Runs Production Systems. O’Reilly Media, 2016. ISBN: 9781491929124
[34] Thomas Limoncelli. “The Time I Stole $10,000 from Bell Labs.” ACM Queue, 第18卷, 第5期, 2020年11月. doi:10.1145/3434571.3434773
[35] Charity Majors. “The Future of Ops Jobs.” acloudguru.com, 2020年8月. 存档于 perma.cc/GRU2-CZG3
[36] Boris Cherkasky. “(Over)Pay as You Go for Your Datastore.” medium.com, 2021年9月. 存档于 perma.cc/Q8TV-2AM2
[37] Shlomi Kushchi. “Serverless Doesn’t Mean DevOpsLess or NoOps.” thenewstack.io, 2023年2月. 存档于 perma.cc/3NJR-AYYU
[38] Erik Bernhardsson. “Storm in the Stratosphere: How the Cloud Will Be Reshuffled.” erikbern.com, 2021年11月. 存档于 perma.cc/SYB2-99P3
[39] Benn Stancil. “The Data OS.” benn.substack.com, 2021年9月. 存档于 perma.cc/WQ43-FHS6
[40] Maria Korolov. “Data Residency Laws Pushing Companies Toward Residency as a Service.” csoonline.com, 2022年1月. 存档于 perma.cc/CHE4-XZZ2
[41] Severin Borenstein. “Can Data Centers Flex Their Power Demand?” energyathaas.wordpress.com, 2025年4月. 存档于 perma.cc/MUD3-A6FF
[42] Bilge Acun, Benjamin Lee, Fiodar Kazhamiaka, Aditya Sundarrajan, Kiwan Maeng, Manoj Chakkaravarthy, David Brooks, 和 Carole-Jean Wu. “Carbon Dependencies in Datacenter Design and Management.” ACM SIGENERGY Energy Informatics Review, 第3卷, 第3期, 第21–26页, 2023年10月. doi:10.1145/3630614.3630619
[43] Kousik Nath. “These Are the Numbers Every Computer Engineer Should Know.” freecodecamp.org, 2019年9月. 存档于 perma.cc/RW73-36RL
[44] Joseph M. Hellerstein, Jose Faleiro, Joseph E. Gonzalez, Johann Schleier-Smith, Vikram Sreekanti, Alexey Tumanov, 和 Chenggang Wu. “Serverless Computing: One Step Forward, Two Steps Back.” arXiv:1812.03651, 2018年12月.
[45] Frank McSherry, Michael Isard, 和 Derek G. Murray. “Scalability! But at What COST?” 第15届USENIX操作系统热点话题研讨会(HotOS),2015年5月.
[46] Cindy Sridharan. Distributed Systems Observability: A Guide to Building Robust Systems. 报告, O’Reilly Media, 2018. 存档于 perma.cc/M6JL-XKCM
[47] Charity Majors. “Observability—A 3-Year Retrospective.” thenewstack.io, 2019年8月. 存档于 perma.cc/CG62-TJWL
[48] Benjamin H. Sigelman, Luiz André Barroso, Mike Burrows, Pat Stephenson, Manoj Plakal, Donald Beaver, Saul Jaspan, 和 Chandan Shanbhag. “Dapper, a Large-Scale Distributed Systems Tracing Infrastructure.” Google技术报告 dapper-2010-1, 2010年4月. 存档于 perma.cc/K7KU-2TMH
[49] Rodrigo Laigner, Yongluan Zhou, Marcos Antonio Vaz Salles, Yijian Liu, 和 Marcos Kalinowski. “Data Management in Microservices: State of the Practice, Challenges, and Research Directions.” Proceedings of the VLDB Endowment, 第14卷, 第13期, 第3348–3361页, 2021年9月. doi:10.14778/3484224.3484232
[50] Jordan Tigani. “Big Data Is Dead.” motherduck.com, 2023年2月. 存档于 perma.cc/HT4Q-K77U
[51] Sam Newman. Building Microservices, 第2版. O’Reilly Media, 2021. ISBN: 9781492034025
[52] Chris Richardson. “Microservices: Decomposing Applications for Deployability and Scalability.” infoq.com, 2014年5月. 存档于 perma.cc/CKN4-YEQ2
[53] Mohammad Shahrad, Rodrigo Fonseca, Íñigo Goiri, Gohar Chaudhry, Paul Batum, Jason Cooke, Eduardo Laureano, Colby Tresness, Mark Russinovich, 和 Ricardo Bianchini. “Serverless in the Wild: Characterizing and Optimizing the Serverless Workload at a Large Cloud Provider.” USENIX年度技术会议(ATC),2020年7月.
[54] Luiz André Barroso, Urs Hölzle, 和 Parthasarathy Ranganathan. The Datacenter as a Computer: Designing Warehouse-Scale Machines, 第3版. Springer Nature, 2019. ISBN: 9783031017612
[55] David Fiala, Frank Mueller, Christian Engelmann, Rolf Riesen, Kurt Ferreira, 和 Ron Brightwell. “Detection and Correction of Silent Data Corruption for Large-Scale High-Performance Computing.” 高性能计算、网络、存储与分析国际会议(SC),2012年11月. doi:10.1109/SC.2012.49
[56] Anna Kornfeld Simpson, Adriana Szekeres, Jacob Nelson, 和 Irene Zhang. “Securing RDMA for High-Performance Datacenter Storage Systems.” 第12届USENIX云计算热点话题研讨会(HotCloud),2020年7月.
[57] Arjun Singh, Joon Ong, Amit Agarwal, Glen Anderson, Ashby Armistead, Roy Bannon, Seb Boving, Gaurav Desai, Bob Felderman, Paulie Germano, Anand Kanagala, Jeff Provost, Jason Simmons, Eiichi Tanda, Jim Wanderer, Urs Hölzle, Stephen Stuart, 和 Amin Vahdat. “Jupiter Rising: A Decade of Clos Topologies and Centralized Control in Google’s Datacenter Network.” ACM数据通信专业组年度会议(SIGCOMM),2015年8月. doi:10.1145/2785956.2787508
[58] Glenn K. Lockwood. “Hadoop’s Uncomfortable Fit in HPC.” glennklockwood.blogspot.co.uk, 2014年5月. 存档于 perma.cc/S8XX-Y67B
[59] Cathy O’Neil. Weapons of Math Destruction: How Big Data Increases Inequality and Threatens Democracy. Crown Publishing, 2016. ISBN: 9780553418811
[60] Supreeth Shastri, Vinay Banakar, Melissa Wasserman, Arun Kumar, 和 Vijay Chidambaram. “Understanding and Benchmarking the Impact of GDPR on Database Systems.” Proceedings of the VLDB Endowment, 第13卷, 第7期, 第1064–1077页, 2020年3月. doi:10.14778/3384345.3384354
[61] Martin Fowler. “Datensparsamkeit.” martinfowler.com, 2013年12月. 存档于 perma.cc/R9QX-CME6
[62] “Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 (General Data Protection Regulation).” Official Journal of the European Union L 119/1, 2016年5月.