
要点
运维和分析用例无法可靠地访问相关、完整和可信赖的数据。需要一种新的数据处理方法。
虽然多跳架构已经存在了几十年,并且可以对接运维和分析用例,但它效率低下、速度慢、成本高且难以复用。
左移方法将下游发生的相同数据处理过程左移(至上游),以便更多团队可以访问相关、完整和可信赖的数据。
数据产品是左移过程的关键部分,构成了整个企业数据通信的基础。
数据合约确保数据产品的健康度,并在内部和外部数据模型之间提供屏障,为数据生产者用户提供稳定且可进化的 API 和明确定义的业务领域边界。
运维和分析用例都面临着同样的问题:它们无法可靠地访问整个组织中相关、完整和可信赖的数据。相反,每个用例往往都需要自己拼凑一些数据访问方式。ETL 管道可能为数据分析用例的数据访问需求提供一部分解决方案,而 REST API 可能为运维用例提供一些临时数据访问请求。
但是,每个独立的解决方案都需要自己的实现和维护,从而导致重复工作、过高的成本以及很多很接近又略有不同的数据集。
有一种方法可以让需要数据的人员和系统更好地使用数据,无论他们是将数据用于运维、分析还是介于两者之间的目的。使用这种方法意味着重新思考那些过时但仍常用的 ETL 模式、昂贵且缓慢的多跳数据处理架构以及数据访问责任分配中普遍存在的“人人为己”的心态。这不仅是一种思维转变,而且是我们对数据处理位置、数据用户以及具体实现的转变。简而言之,这是一种左移,将你已经在做(或将要做)的下游工作向左移(到上游),以便所有人都能从中受益。
但我们从哪里向左移呢?
重新思考数据湖和数据仓库
数据湖通常是一种 多跳架构,其中数据经过多次处理和复制,最终达到某种水平的质量和组织度,可以为特定业务用例提供支持。数据从左到右流动,从某种形式的 ETL 开始,从源系统进入数据湖或数据仓库。

多跳架构已经存在了几十年,一直是弥合运维与分析鸿沟的架构之一。然而,它们本质上就是效率低下、速度慢、成本高昂且难以复用的。
奖牌架构(medallion architecture) 是当今最流行的多跳架构形式。根据奥运奖牌标准,它分为三种奖牌或层:铜牌、银牌和金牌。每一层都代表着更高的质量、可靠性和保证:铜牌最弱,金牌最强。
铜牌层:铜牌层是原始导入数据的着陆区,通常作为源数据模型的镜像。然后,数据处理者向原始数据添加结构、模式、增强和过滤。铜牌层是更高质量的银牌层数据集的主要数据源。
银牌层:银牌层提供经过过滤、清理、结构化、标准化和(重新)建模的数据,适用于分析、报告和进一步的高级计算。它们是计算分析、构建报告和填充仪表板的构建块,通常围绕重要的业务实体来组织。例如,它可能包含代表所有业务客户、销售、应收账款、库存和客户互动的数据集,每个数据集都有着正确的格式、经过模式化、删除了重复数据,并被验证为“值得信赖的规范数据”。
金牌层:该层提供“业务级”和“应用程序对齐”的数据集,专门为特定应用程序、用例、项目、报告或数据导出提供数据。金牌层数据主要是非规范化的,并针对读取进行了优化,但你可能仍需要在查询时对接其他数据集。银牌层提供了“构建块”,而金牌层提供了“构建体”,后者由块构建而成,这些块通过附加逻辑粘合在一起。

奖牌架构,多跳架构的一个流行版本
奖牌架构以及所有多跳架构都存在一些严重问题。我们来看看具体情况:
缺陷 #1:消费者负责数据访问
多跳奖牌模型以一个拉取系统为前提。下游数据处理者必须首先创建一个 ETL 作业,将数据拉入奖牌架构。接下来,他们必须对其进行重新建模、清理,并将其转换为可用形式,然后才能开始实际工作。这是一种被动且站不住脚的立场,因为消费者承担着保持数据可用和运行的全部责任,而对源模型没有所有权,甚至没有影响力。
此外,这里的 ETL 与源数据模型耦合,带来了非常紧密且脆弱的耦合关系。对上游系统(例如数据库架构)所做的任何更改都可能导致管道中断。
缺陷 #2:奖牌架构成本高昂
填充铜牌层需要大量的数据复制和处理能力。然后,我们要立即再次处理和复制这些数据,以使其达到银牌层质量。每个步骤都会产生成本——加载数据、网络传输、将副本写回磁盘和计算资源——这些成本很快就会累积成一大笔费用。它的构建和维护成本本身就很高,并且会导致大量资源浪费。
再考虑以消费者为中心的数据访问责任时,上述成本可能会进一步膨胀。不清楚可以使用或不能使用哪些数据的消费者倾向于从源头构建自己的管道,从而增加计算和人力资源的总成本。结果可能是金牌层项目无法提供足够的投资回报,仅仅因为这种模式产生的成本太高了。
缺陷 #3:恢复数据质量很困难
假设你成功地将数据从系统中 ETL 到数据湖中了。现在,你需要对其进行非规范化、重构、标准化、重塑,并使其有意义,并且不能犯任何错误。
美国曾经流行的电视节目《犯罪现场调查员》(CSI)给观众带来了一种对恢复数据的结构和形式这一操作的不切实际的印象。在一个场景中,一名调查员告诉另一名调查员“增强”计算机屏幕上的图像,于是另一名调查员把图像放大了很多倍,从嫌疑人的太阳镜上反射出来的模糊的像素化图像突然变成了清晰的线索。实际上,我们只会得到一些非常块状像素的特写,无论多少“增强”都无法修复它。
这是一个警示故事。铜牌层的创建者不是源域模型的专家,但他们要负责重建精确、完美的数据。为了实现这一目标,他们所做的任何工作都是非常有挑战性的,尽管他们可能重建出和源数据模型所代表的内容很接近的结果,但它可能并不完全正确。这就是下一个问题所在。
在更实际的场景中,考虑一个人输入的三个地址:123 Fake Street、123 Fake st. 和 123 FAKE STR。哪一个是正确的地址?数据的独立消费者会将其标准化为哪一个?虽然这种非标准化格式的每个消费者都会尽力做出明智而理性的处理决策,但这些相对平凡的数据清理步骤可能会造成严重破坏。一个系统可能会将它们合并为一个地址,而另一个系统可能不会,从而导致不同的结果和相互矛盾的报告。
从源头获取正确的高保真数据,尽可能清晰明了、保持最佳结构,这一工作是无可替代的。如果你做得没问题,就能将其复用于你的所有用例——运维、分析以及介于两者之间的一切。
缺陷 #4:铜牌层很脆弱
铜牌层是从上游系统中提取的所有数据的垃圾场。它承担着过多的责任,并且在源系统数据和(据称)更值得信赖的银牌层数据之间建立了复杂的映射。它是一个复杂的纸牌屋,依赖 ETL 和数据清理作业的编排,同时又容易因上游输入数据的任何更改而中断。
结果是铜牌层经常以某种方式被破坏,需要重新处理数据并进行事后分析,从而导致报告、仪表板和分析不一致。如果你足够幸运地注意到问题的存在,并且没有收到非常愤怒的客户抱怨,那就会发生这种情况。
信任在业务中至关重要。我工作过的所有数据组织都有这样一句话,可以归结为:“信任难以建立,又容易崩塌”。
糟糕的数据会让你的客户失去对你的信任。想象一下,在仪表板上向他们显示一个值,但在账单中向他们收取另一个金额,看看他们有多高兴吧。相似但不同的数据集在奖牌架构中很常见,因为标准化数据的所有工作都是消费者负责的。无论你和你的团队多么勤奋、善意或警觉,都很容易犯错误。
缺陷 #5:运维负载没有数据可重用性
推送到分析端点的数据大部分(通常只)停留在分析空间中,所有清理、标准化、模式化和转换工作也是如此。它通常由定期批处理作业处理,这些作业对于运维用例来说往往太慢了。
相反,运维负载会开发自己的技术和工具来访问它们需要的数据,进一步扩大了运维和分析空间之间的鸿沟。
左移使访问数据变得更容易、更便宜、更简单
左移是对我们如何在组织内传递数据的一种新的理念。从本质上讲,它是让你将已经在做的(或计划做的)工作向左移动,以便每个人都能从中受益。左移消除了重复的管道,降低了不良数据的风险和影响,并让你利用高质量的数据源处理运营和分析用例。左移是迭代和模块化的——你可以只将一个数据集向左移动,也可以移动多个数据集。这完全取决于你的具体需求。

左移之所以有效,是因为你只是在做你已经在做或将要做的工作,只是把它们推到上游了。例如,你已经:
将内部域模型映射到了数据湖 / 仓库中的外部域
尝试将非结构化、低保真度数据的保真度恢复到其数据源的高保真度状态
构建适当的银牌层数据集,用作更复杂工作的构建块
数据产品 提供了定义明确、高质量、可互运维且受支持的数据,其他团队、人员和系统可以根据需要使用这些数据。数据产品可以帮助轻松访问数据,而无需消费者自行寻找访问方式(缺陷 #1)。可将数据产品视为一等数据公民,其发布内容具有与你或你的企业创建的任何其他产品相同的保证和质量。
之前将原始铜牌数据转换为结构良好的银牌数据的所有逻辑都被移出数据湖,并放入数据产品的边界中。清理、重构和架构实现会尽可能靠近源头来执行,以便你在流程早期就获得干净且定义明确的数据模型。这样一来,我们就无需清理和标准化数据源(缺陷 3),而且只需标准化和清理一次,而不是在多个下游系统中多次清理,从而降低清理成本(缺陷 2)。
我们稍后会进一步讨论正式的数据产品定义,但首先,我们先将注意力转向数据产品客户(人员、团队和系统)如何访问数据这个话题。
以流或表的形式访问数据产品
数据产品可以通过多种方式提供数据——也称为模式。例如,通过流(通常是 Apache Kafka 主题)和表(通常是某种基于 Parquet 的结构)提供数据。
分析用例传统上依赖于定期批处理作业和表格数据。然而,现代用例往往需要低延迟流来完成许多分析任务,例如支持客户仪表板、预测和塑造用户参与度以及监控业务的实时健康状况,等等。

具有流和表模式的数据产品
但流也可以驱动运维用例,这很好地解决了我们的缺陷 #5。简而言之,你用于标准化和构造表模式数据的那些逻辑非常适合生成流模式。你只需对流 / 表数据产品投资一次,即可同时支持运维和分析用例。
Apache Iceberg 是从事件流中提供物化表的主要方法之一,因此你可以将其插入所需的任何分析处理引擎,而无需额外复制数据。你可以节省大量时间和精力(缺陷 #1 和 #3)和金钱(缺陷 #2),同时减少误解、重复管道,还能大大抑制相似但不同的数据集的增加(缺陷 #4)。
你可以使用 Apache Kafka 连接器创建代表事件流的 Iceberg 表。一些服务提供商还提供自己的第一方选项,以进一步降低复杂性,例如 Confluent 的 Tableflow 功能可将任何 Kafka 主题直接转换为 Iceberg 表。
你可能会问,“但是如何保持流和表的一致性?”
最简单的方法之一是使用直写方法 - 首先将数据写入流,然后从流中物化表。你可以使用连接器来生成表,也可以编写一些自定义代码将流物化为一个表来表示。

具有从流中物化的表模式的一个数据产品
从一开始就写入流可以解决整个组织的所有事件驱动用例。派生物化表作为数据产品的一部分,可实现很多基于表的用例,例如批量加载数据、基于批处理的查询以及为不需要流数据的系统提供支持。
在结束之前还有一些事情需要介绍。现在我们来更深入地了解数据产品本身。
数据产品和数据合约
数据产品主要是对你已经完成或需要完成的工作进行形式化,以使数据在整个组织中可用。你创建和管理数据产品的严谨程度将取决于你的公司文化、业务需求和数据问题。
当你有许多重要的数据集分布在多个系统、域和团队中时,通常需要采用严格而正式的方法。简而言之,依赖数据的人越多,你构建、管理和监控数据产品就应该越严格。
构建成功数据产品的常见实践包括:
指定一名数据产品所有者,负责管理客户请求和发布工作。此人可能已经是产品所有者,也可能是高级开发人员或团队负责人。但重要的是,他们是拥有原始数据源的团队的一员,并且熟悉内部数据域模型。
咨询客户(其他团队、人员、系统)。数据产品所有者负责确保数据产品能够满足数据要求。
建立发布管理周期,以审查、测试和集成数据产品的创建、更新和删除工作。将数据产品检查流程添加到现有部署管道是确保数据产品质量的关键第一步。
提供并填写一个人类可读的数据目录,以便轻松发现数据,包括示例数据、用例,以及问题和帮助的联系点(例如数据产品所有者)。
验证和确认 以确保数据产品遵守其创建期间建立的数据合约。
数据合约为所有用户(包括流和表模式)提供了数据产品及其 API 的形式和功能的正式协议。数据合约还在内部和外部数据模型之间提供了一道屏障,为数据产品用户提供了稳定且可演进的 API 以及对其他业务领域明确定义的边界。
数据合约的常见要点包括:
特定的模式(schema)技术,例如 Avro、Protobuf 或 JSONSchema,这些都是最流行的事件模式。你也可以选择表格格式,如今 Parquet 显然是最受欢迎的。
数据的实际模式,包括字段的名称、类型和默认值。对于流,它还包括了事件键信息,用于对流分区的键分区策略。
模式演进规则,与模式技术密切相关。例如,如果你需要向模式添加新字段(类似于向数据库表添加列),模式演进规则将为你提供一个更新数据的框架,而不会对下游消费者造成意外破坏(进一步缓解缺陷 #4)。
社会责任,例如如果你对数据有疑问,应该联系谁,以及如果出现问题,应该获得什么级别的支持。
与支持有关的服务级别协议(SLA)。如果数据产品在半夜出现故障,那么一级 SLA 可能会要求有人起床修复,而四级 SLA 可能会在接下来的 3 个工作日内修复。
创建数据合同时需要潜在消费者的意见,尤其是那些依赖原始不可靠数据的消费者。是什么让他们感到痛苦?他们想要修复什么?他们需要哪些保证来避免由未知更改导致的故障?
然后,这些潜在消费者与数据产品所有者及其支持团队成员一起敲定数据产品的角色、职责、数据定义和变更管理框架。
你该向左移动多远?
也许最常见的问题之一是左移方法的左移程度。答案会根据几个因素而有所不同,但通常会遵循三种主要模式之一。
第一种模式是完全向左移动。数据产品是在源系统的应用程序代码中创建的,数据以格式良好的事件形式原生地发送到事件流。数据产品所有者是应用程序团队的成员,数据合同与应用程序的所有其他 API 一起管理。应用程序团队完全愿意并能够构建和管理数据产品。

类型 1:向左移动到头
但并非所有系统都允许这种级别的集成。例如,遗留应用程序可能会限制那些安全性不足的进一步更改。社会技术因素也可能是另一个因素,比如源应用程序团队拒绝提供更深层次的应用程序集成。在这种情况下,你必须在源应用程序之外构建数据产品,并且你还需要搞清楚源应用程序团队愿意提供什么级别的支持。
虽然社会技术因素可能会阻碍向左移动,但现实情况是数据清理和标准化仍然需要由某个地方的某个人来完成。一种不太理想但仍然可行的方法是任命一个团队来管理源应用程序之外的数据产品。这种类型 2 模式如下所示,它利用变更数据捕获连接器从数据库获取数据并进行转换(例如标准化某些字段),然后将其写入输出帐户主题。

类型 2:左移,但位于源应用程序之外
这一集成级别的缺点是,对数据库表的更改可能会破坏数据产品。但这可能是一种更可接受的模式,因为应用程序团队不再需要处理那些自己的管道已被破坏的团队和系统的投诉。相反,他们可以简单地与数据产品所有者打交道,减轻自己的压力,并为他们未来的进一步合作打开大门。
这两种模式都假设你可以从单个数据库中获取所需的所有数据。但如果你需要来自多个系统的数据怎么办?这就引出了类型 3 集成,我们使用完全外部的流处理器将来自多个流的数据整合到一个数据产品中。

类型 3:从多个流构建数据产品
第三种类型往往出现在组织随着左移而成熟时,并可能产生飞轮效应。随着越来越多的源系统提供数据,访问数据变得更加容易——对易于混合和匹配的数据的需求不断增加,你也不用再构建和管理自己的数据管道并自己完成所有工作。
在此示例中,我们看到 Flink SQL 被用于创建丰富的订单主题,它将三个不同源系统提供的帐户信息、订单信息和产品信息结合在一起。
总 结
左移为组织中所有需要它的人提供了干净、可靠且可访问的数据。它最终会减少复杂性、开销和故障修复工作,并让你和你的同事腾出时间去处理其他更有价值的问题。数据产品是左移策略的支柱,是整个组织健康数据通信的基础。
左移的重点在于重新协商工作完成的位置以及负责确保工作正确完成的人员。虽然看起来我们是在增加工作量,但我们只是把在铜牌层中要做的工作(例如清理、标准化和模式化)转移到上游。这种类型的工作最容易左移,因为它将澄清数据含义的责任放在最了解数据的人们身上——也就是最初创建数据的团队、人员和系统。
你可以选择使用流来执行更高级的模式——例如复杂的基于时间的聚合、特定于业务的应用程序逻辑或其他类型的处理工作。然而,左移的关键只是建立对高质量数据产品的轻松访问能力,以取代通常在铜牌层中完成的工作,使所有人而不是少数人受益。
作者介绍
Adam Bellemare 是 Confluent 技术战略组的首席技术专家。他是 O’Reilly 的《构建事件驱动的微服务》(2020 年)和《构建事件驱动的数据网格》(2023 年)的作者。他的工作重点是事件驱动架构理论与实践、事件驱动的微服务和事件流设计原则。在加入 Confluent 之前,Adam 曾在多家电子商务公司担任大数据平台工程师,专注于使用 Apache Spark、HDFS 和早期 S3 构建批处理解决方案,之后将注意力转向事件驱动架构。从那时起,他主要专注于使用 Apache Kafka 构建微(和常规)服务,并宣传将有用的业务事实发布为通用数据访问层的好处。
原文链接:
The End of the Bronze Age: Rethinking the Medallion Architecture(https://www.infoq.com/articles/rethinking-medallion-architecture/)
评论