构建 Medallion 架构——数据架构的演进

构建稳健的数据架构是数据管理中最具挑战性的环节之一。 从数据采集、转换、分发到最终消费,整条处理流程会因多种因素而显著不同:包括治理方式、所用工具、组织的风险画像、规模与成熟度、用例需求,以及性能、灵活性、成本管理等其他诉求。

尽管存在这些差异,每一种数据架构都包含若干基本组件。我常用一个三层架构设计 的隐喻来讨论这些组件------这一概念最初见于我的前作 Data Management at Scale (O'Reilly)。这个设计已帮助许多组织在概念层面对其数据管理策略进行建模与分解。它包含三层:第一层是各类数据提供方;第二层是分发平台;第三层是数据消费者。此外,还需要一层贯穿全局的元数据与治理层,用于管理与监管整套数据架构。该设计可参见图 1-1 的示意。

图 1-1 三层架构设计

从左到右,各层的简要概览如下。

第一层

这一层由各类数据提供方构成,代表了从不同来源抽取的数据。被抽取的数据在不同组织之间呈现出多样的数据类型、格式与落地位置。

第二层

这一层代表分发平台。由于可选的工具与技术极为繁多,它也最为复杂。组织往往需要在数百、甚至上千种商用与开源方案中做出集成选择。

第三层

这一层由数据消费者构成,其特点是消费数据服务。数据服务借助商业智能(BI)、机器学习与人工智能(AI)来提供预测、自动化与实时洞察;也有一些服务负责基础的存储与数据处理。由于每个业务问题都需要定制化解法,这一层的技术与应用类型非常多样,两类服务在现代数据架构中都不可或缺。

为完整刻画这一高层架构,我通常会在讨论中再绘制一层元数据与治理的总控层,它在监管与管理整套数据架构中扮演关键角色。

这幅三层示意图,特别是对中间层内部架构的着墨,展示了组织内部数据平台管理的演进 :从传统的封闭式数据仓库系统,转向更具弹性、开源且分布式的数据架构。这一转变由一组开源工具与框架推动,它们统称为现代数据栈(modern data stack)

问题在于,现代数据栈本身并不是 一套完整的数据平台。它需要把许多相互独立的服务与工具拼合在一起,而每个组件只解决数据处理与管理中的某一部分。每个服务/工具都带有自己的数据交换标准、安全协议与元数据管理方式;并且许多服务在功能上彼此重叠,进一步增加了落地与使用的复杂度。因此,要有效利用现代数据栈,必须先谨慎选型,再对每个组件进行细致的集成。这一道集成过程本身就构成了显著的准入门槛

这并非某一家厂商的失败------**而是整个市场的失败。**¹

------ Benn Stancil

技术提供方也洞察到了这一问题。他们已经认识到:集成与管理基础设施、数据存储与计算的复杂性极高。近年来在Apache Spark开源表格式 (如 Delta Lake)上的开发与标准化取得了显著进展,催生出一体化的软件平台,从而简化了数据处理方式。许多数据工程师青睐这些平台,原因在于其创新能力与工程易用性。此外,那些采用 Spark 与 Delta Lake 的组织,会发现**奖章分层架构(Medallion architecture)**尤为有利(下一节会给出定义)。该架构能够充分发挥一套稳健、可扩展且高效的端到端数据管理与分析框架的优势。

什么是"奖章分层(Medallion)架构?

"奖章分层架构"是一种数据设计范式,常用于在湖仓(lakehouse)中以三层 方式对数据平台进行逻辑组织,其目标是在数据沿着架构各层(从 Bronze ⇒ Silver ⇒ Gold )流动的过程中,逐步、增量式地提升数据的结构化程度与质量。第 3 章将深入剖析每一层的细节。这里先给出简要概览:

Bronze 层

原生结构 存放来自各类源的原始数据,既作为历史留存,也作为可靠的初始落地层。

Silver 层

通过质量校验、标准化、去重 以及其他转换,对原始数据进行细化与规范,作为已处理但仍具颗粒度的数据的过渡层,提升数据的一致性与质量,便于开展复杂分析。

Gold 层

围绕具体业务洞察与决策对精炼数据进行优化 ,执行汇总、聚合与专题增强 ,面向高层报表与分析,强调性能与可扩展性,为关键指标与洞察提供快速访问。

如图 1-2 所示,这样的设计为支撑业务增长与发展落地各类应用/用例提供了极佳的切入点。

图 1-2 奖章分层架构:将数据组织为三层,使其在逐层推进过程中不断增强结构与质量

奖章分层架构为不同层提供了业务友好 的标签。然而,许多企业并不清楚如何有效地分层与建模,常常花费大量时间讨论选型、集成、功能重叠 等问题;他们难以把目标合理放入不同"区域",也难以准确理解 "Bronze、Silver、Gold" 的含义。同时还会产生关于治理与扩展 的疑问,例如:哪些部分可以做成元数据驱动,通过灵活配置与自动化来实现?选择一个"全家桶"平台并不会自动回答这些问题或替你解决这些挑战。

在具体回答这些问题、着手设计一套奖章分层架构之前,首先理解数据架构的演进 至关重要:这些平台从何而来?有哪些设计原则 至今仍然适用、必须遵循?理解数据架构的历史与基本原则,能为你有效使用这些端到端平台打下坚实基础。本章旨在通过回顾历史发展、实践观察、通用模式、最佳实践与基本原则作一番导论。借助这些背景、推理与经验教训,你将为第二部分的学习------如何设计并实现你自己的数据架构------做好充分准备。

如果你觉得自己已非常熟悉数据架构基础,可以直接跳到第 3 章,阅读对奖章分层架构及其各层的详细讨论。否则,不妨与我一起从传统数据仓库 谈起,随后探讨数据湖(含 Hadoop)兴起背后的模式,讨论各类架构的优缺点与经验教训,并说明这些演进如何关联到当代的最佳实践。最后,我们将深入湖仓与奖章分层架构(两者关系密切),并在该部分对不同的技术提供方加以讨论。

数据仓库架构简史(A Brief History of Data Warehouse Architecture)

让我们把时间拨回到 1990 年代。当时,"数据仓库(data warehousing)"作为一种将数据收集并整合到统一集合中的通行实践兴起。其目标是在组织内部建立唯一一致的事实来源,为公司层面的业务决策提供关键依据。

这一交付数据洞察的过程包含诸多步骤:从各类源系统采集 数据、将其转换 为一致格式、并装载至一个中心化的存储库。第 3 章会更详细地讨论这些过程。这里我们先将注意力集中在图 1-3 所示的数据仓库架构本身(同时包含数据源与消费侧服务,例如报表工具)。

图 1-3 典型的数据仓库架构

我将从左至右分析各层:先是左侧的 OLTP 系统,再到中间的数据仓库;右侧的数据集市(data marts)会在"Inmon 方法论"部分介绍与讨论。

OLTP 系统(OLTP Systems)

大多数源系统都是为事务型/运营型 诉求设计的,反映了早期计算在人机交易与记录维护方面的需求。图 1-3 左侧这些来源常被称为联机事务处理系统(OLTP, online transaction processing) ,凸显其关键的运营角色。

深入观察一个 OLTP 系统,你会发现运营负载 通常相当可预测。理解 OLTP 的使用方式与典型负载至关重要:查询相对直白、返回量较小------如读取一条记录、更新一条记录、删除一条记录等。其底层物理数据模型被设计(并优化)以便支持这些可预测的查询。因此,OLTP 系统通常采用**范式化(normalized)**设计,力求每个属性只存储一次。

数据库"范式化"与"反范式化"(DATABASE NORMALIZATION VERSUS DENORMALIZATION)

在关系型数据库语境下,范式化 通过一系列"范式(normal forms)"规则重构数据,以减少冗余、提升完整性 。实践中最常用的是第三范式(3NF) 。范式化让数据更高效、一致地存储,便于维护与检索。因此,所谓"规范化的数据",就是指为提高存储效率与完整性而组织起来的数据。

反范式化 则有意引入冗余,以提升查询性能与检索速度。它常用于数据仓库与分析场景以优化读取与处理:通过反范式化可减少查询时需要的关联(JOIN)次数,从而显著改善性能。但由此也可能带来数据完整性问题------若冗余数据未被妥善管理,就可能不一致。

许多 OLTP 系统将完整性与稳定性 置于优先地位。为此,它们通常采用遵循 ACID(原子性、一致性、隔离性、持久性)性质的数据库管理系统。² 这些性质对稳定运行业务交易至关重要,有助于在操作中管理与保护数据。然而,OLTP 的设计会带来若干重要影响,尤其在与组织讨论时需要明确:

其一 ,运营系统并不擅长 直接提供对业务或特定域的全面、汇总的分析视图 。原因在于,从高度范式化的数据模型中为复杂查询抽取数据十分困难,会给 OLTP 带来沉重压力。获取所需洞察往往需要复杂查询------涉及更多数据与数据组合,即需要关联或分组很多表 。这类查询通常资源开销很大 ,若执行过于频繁(尤其在大数据量下)就会触及性能上限。³ 一旦运营系统因此变得不可预测,就可能对业务产生负面影响。因此,在采用范式化设计时必须仔细评估其潜在影响:它适合某些目的,但不一定适合提供全面的分析视图。

其二 ,对高完整性、性能与可用性 的严格要求常使 OLTP 系统成本较高。典型优化策略包括:迁移未使用数据 和/或仅保留最新 数据以便系统聚焦近期事务,从而实现即时更新 而不保留历史版本。有时(在数据虚拟化⁴语境下)工程师会主张将全部历史数据 保留在 OLTP 内,而非转移至数据仓库/数据湖/湖仓。但这往往不切实际 :OLTP 的固有设计并不适合承载大量历史数据,这会拖慢事务处理与更新;同时还会带来维护与适应性挑战。

其三 ,OLTP 系统最初多被针对具体业务 优化、且相互隔离 。各系统的数据存储方式彼此不同。这种隔离与多样性使单一系统 难以在没有大量集成工作的前提下提供统一视图。

通过将分析负载与运营系统分离 ,组织可以解决上述许多问题。此举不仅有助于保留历史数据 的完整性,还能让系统针对分析处理进行优化。此外,将多源数据以统一格式 进行存储与处理,能比单一系统提供更具凝聚力的视图。行业中的标准做法,是把这些数据迁移到一个中间层,例如数据仓库。

数据仓库(Data Warehouses)

数据仓库 是万流归宗的中心枢纽:用于从各源系统采集并组织 数据,并将其转换成一致格式,以支持联机分析处理(OLAP) ------面向分析需求的复杂处理。由于离线分析通常对业务的"即时性/关键性"要求较低,因此其完整性可用性 指标可相对宽松。与 OLTP 为完整性与低冗余而优化不同,OLAP 强调分析性能 :以读为主、写为辅 ,更适合对密集读取 进行优化。为适配不同的读模式,OLAP 可复制 数据以支持多种分析场景。OLAP 数据库中的表通常并非高度范式化,而是预处理为反范式化结构 :表往往是体量大、扁平化、稀疏的数据拷贝。

TIP
Deciphering Data Architectures(James Serra 著,O'Reilly)系统概述了数据仓库、数据湖与湖仓等数据架构,是理解数据架构演进及其背后原理的优质参考。

要把数据装载进数据仓库,首先需要从不同源系统抽取(Extract) 。这一步包括理解源数据,并将所需数据读取并复制 到一个中间区域(staging area) ,以便后续处理。正如图 1-3 所示,暂存区 位于运营源系统与数据集成/呈现区域之间。该区域既是存储区 ,也是一组流程的集合,通常被称为 ETL(抽取、转换、装载)

暂存区(The Staging Area)

暂存区(亦称落地区/暂存层 )可以有不同形态:从关系型数据库到文件存储各不相同。关系库更灵活但更昂贵 ;文件存储廉价但功能有限 。暂存区也常用于保留历史副本 :当数据仓库受损需重建时有利于重处理 。不同组织在暂存区保留旧数据交付(历史副本)的数量差异很大。我遇到过需为审计 保留多年 全部交付(含更正)的案例;也见过在处理成功后或超过固定时限即清空 暂存区(非持久化)的做法,以降低存储成本 或满足治理要求。

抽取与暂存的复杂性在于:不同源系统的数据格式 可能完全不同。因此,具体摄取(ingestion)过程会因源类型而显著变化。有些系统允许直接的数据库访问 ,另一些则通过 API 摄取。尽管技术在发展,许多数据收集流程仍依赖文件抽取 ,因为在大体量场景下,它往往更具性价比、实现更简单

当技术层面的数据被抽取到暂存区后,会进行一系列预处理/转换 :如数据清洗、数据丰富、主数据管理(MDM)、赋予仓库键 等。这些步骤都是在将多源数据 进行组合、转换并装载至数据仓库的集成与呈现 区域之前完成的。在多数情况下,你需要对源自事务系统(见 OLTP 部分)的高度范式化且复杂的结构做大量重构。

NOTE

构建现代数据架构 时,数据转换问题依然存在,无可回避 。为了让数据对分析处理真正有用,它必须被清洗并完成集成

那么,问题来了:在集成层呈现层 应如何进行数据建模 ?下面我们讨论两种常见方法论:InmonKimball

Inmon 方法论(Inmon Methodology)

时至今日,数据工程师中仍存在困惑:在抽取与转换之后,数据是否应先在物理上建模为范式化结构 ,再装载到呈现层供查询与报表使用?困惑的根源在于各方法处理数据的路径不同

传统上,数据仓库是一种昂贵 的系统。20 世纪 90 年代初兴起的 Inmon 方法 (因其提出者 Bill Inmon 而得名,见图 1-4)是一种广泛采用、基于范式化数据模型的方法,通常使用**第三范式(3NF)**建模。

3NF 将数据组织进冗余最小 的表中,确保每份数据只存储一次,消除重复;并通过确保每个非主属性 只依赖于主键 来维护参照完整性 。这种方法能显著减少所需存储空间。此外,它主张建立一个中心化、结构高度规范企业数据仓库(EDW) ,服务整个组织。

为提升查询与性能,Inmon 方法还引入呈现层:数据集市(data marts) 。它们建立在数据已高效存放于集成层 之后。数据集市通常只包含集成层数据的子集 ,面向特定用例/团队/用户 。其数据常以星型模型 组织,因为该模型已针对读性能 优化。星型中结构的简洁与反范式化 ,正是其适合读密集型工作的关键原因。因此也可以说,相比集成层,数据集市中的数据存储效率较低 。此外,把集成层的 3NF 转换为数据集市的反范式模型 通常需要大量工作:包括复杂的 JOIN 来重组数据,以恢复其完整语义用于更有效的分析与查询。

图 1-4 Inmon 方法:自上而下的设计。先建中心化数据仓库,再由此派生数据集市。

许多实践者对"集成层用范式化、呈现层用维度模型"的做法持保留意见,原因在于数据被抽取-转换-装载两次 :先 ETL 至范式化的集成层,再重复一次以最终装载至维度模型。显然,这一两步流程需要更多开发资源与时间 ,也增加了周期性装载/更新 的时间与存储 开销。另一个缺点是:若要给某数据集市新增数据,必须先把数据加入集成层 。由于开发需要时间且对集成层的改动需谨慎推进,需要新数据的用户往往不得不更久地等待

此外,在 Inmon 集成层中,数据冗余 (不必要的重复)经常被指认为问题。但在云计算时代 ,这一观点的分量有所下降:云存储 已相当低价 ,尽管计算成本 可能仍高。也因为计算成本较高,许多专家如今更倾向于Kimball 的数据建模方法。

Kimball 方法论(Kimball Methodology)

Kimball 方法论 以其提出者 Ralph Kimball 命名,作为一种数据建模技术于 1996 年提出,常用于数据仓库。⁵ 它聚焦于维度表 的构建,以支持高效的分析处理。在这种方法中,通常 为业务需求构建维度建模的数据集市(dimensional data marts) 。为此,Kimball 推荐采用**星型模型(star schema)**的维度建模技术。

图 1-5 展示了 Kimball 方法论的抽象表示。

图 1-5 Kimball 方法论:自下而上的数据仓库构建思路

在这种建模方法中,数据仓库的集成层 被视为维度表的集合 ------它们是从源系统的交易数据派生而来。一旦数据进入集成层,其结构就已为读性能做了优化;这些数据更扁平、稀疏 ,在形态上与 Inmon 方法中的数据集市相似。但与 Inmon 不同,Kimball 的集成层即由维度/事实表构成 ,它们反过来成为数据集市的基础。因此,Kimball 不仅承认数据集市的存在,还认为其对性能优化与子集查询 至关重要。数据集市允许根据特定用户群的需要,对持久化的数据副本进行聚合或改造 。值得一提的是,数据集市也可以是虚拟的 :即在集成层既有的维度表与事实表之上,构建维度化的逻辑视图,以获得更高的灵活性与效率。

关于数据仓库各层职责的常见混淆(CONFUSION ABOUT THE FUNCTIONS OF DATA WAREHOUSE LAYERS)

需要澄清的是,围绕数据仓库各层职责的混淆很常见,这与在奖章分层(Medallion)架构 里对"分层"的困惑如出一辙。总体架构的中间部分通常由若干层构成,它们像软件架构中的分层一样,被设计成职责清晰、各司其职

  • 暂存/摄取层(staging/ingestion) :落原始数据,用于将源系统与数据仓库解耦
  • 集成/转换层(integration/transformation) :在满足暂存层验收标准后,将清洗、校正、丰富并转换 后的数据以统一模型 存储;在此完成口径统一 (格式、类型、命名、结构、关系标准化),并保留历史以刻画随时间的变化。
  • 呈现层(presentation) :为特定用例挑选数据并重建模型,以满足该用例的专属需求。

同时也要认识到:出于可审计性灵活性 等原因,偏离"三层"传统设计是合理 的。有的组织会加一层用于审计(先将各源映射到目标模型 ,再与其它来源合并);也有将暂存层拆成两部分:低成本文件存储 保留所有交付,关系库 只保存最近的已验证 数据。要点是:层/区的数量取决于你的需求,没有唯一正确答案,关键在于做对权衡。

为支撑这种维度建模方法,Kimball 引入了**一致维(conformed dimensions)的概念:即被不同用户群共享并复用的关键维度;同时引入用缓慢变化维(SCD, slowly changing dimensions)**记录历史变更的技术。

SCD 指以缓慢且可预期 方式捕捉历史变化的维度表,亦即带有"随时间变化属性"的维度。常用类型有 SCD1/2/3

  • SCD1(覆盖/overwrite) :直接用新信息覆盖 仓库中的既有记录。适用于不需要历史、只关心当前值的场景;缺点是无法追踪历史变化。
  • SCD2(新增行/add new row) :每次变化新增一行 ,保留原记录。适用于需要完整历史 的场景;通过为新旧记录使用不同主键值,得以维护随时间的全量历史
  • SCD3(新增列/add new attribute) :在原记录上新增属性列 来追踪变化。适用于只需追踪少量 属性的场景;局限在于只能保存有限的历史(通常仅一版"前一状态")。

在现代数据架构时代的角色

在现代数据架构中,诸如 InmonKimball 的建模方法仍然是有效管理与利用数据 的关键。它们通过在摄取、集成与一致化、消费 之间划清边界,帮助人们理解并高效使用复杂数据;通过建立稳健的数据及其关系 的表达,既方便技术人员,也便于非技术干系人使用。同时,合理的建模有助于性能与查询优化 ,让定位/获取特定数据更容易、更高效;并支撑更好的数据治理与安全(清晰的模型便于实施访问控制与使用策略)。

传统数据仓库的要点回顾(Key Takeaways from Traditional Data Warehouses)

至此,我们对传统数据仓库的讨论告一段落。我们回顾了 InmonKimball 两种方法论,它们在今天仍具现实意义。要点如下:

  1. 分层并不新鲜 :它被证明是拆分关注点、更高效组织与管理数据的有效策略。
  2. 数据建模至关重要 :它关系到灵活性降低冗余提升性能 ,并成为业务接口。建模做得好,是任何数据管理系统有效运作的前提。
  3. 软硬一体的工程观 :传统数据仓库常本地部署计算与存储耦合紧密 ,利用复杂软件充分压榨硬件性能,通常通过垂直扩展来增强能力。尽管成本与弹性上有局限,这类系统曾长期被偏好,且在特定场景仍有价值。
  4. 价值与局限并存 :数据仓库能提供高质量、标准化 的数据,是决策所必需,其效能来自成熟的建模存储-硬件一体化优化 。但基于传统 RDBMS 的架构在应对快速增长的数据量 时面临存储与扩展性 挑战,纵向扩展 有上限且昂贵;此外,在非结构化数据机器学习 等多样负载支撑上缺乏灵活性。于是工程界开始探索能够化解这些问题的其它架构,这也引出下一节的数据湖架构

数据湖简史(A Brief History of Data Lakes)

数据湖(data lake)的出现是为弥补传统数据仓库的不足。自 2000 年代中期起,它伴随开源软件的兴起而逐渐流行。与前辈不同,数据湖引入了一种新的分布式架构 ,可以管理非结构化、半结构化与结构化等多种形态的海量数据,这种灵活性显著扩大了数据的可用范围。

数据湖依托开源软件 ,因此可运行在任何标准或廉价的通用硬件 之上。相较于专有 RDBMS 所需的昂贵硬件集群,这标志着大数据解决方案构建方式的重大转变。此外,将机器学习技术融入数据湖,使其能力超越了传统数据仓库以报表为主的用途。关于数据湖的结构,可参见图 1-6 的示意。

图 1-6 典型数据湖架构(存放原始数据副本)

第一代数据湖主要采用 Hadoop ------一个著名的开源大数据框架,包含多种工具与服务。其核心是 MapReduce 编程框架与 HDFS(Hadoop Distributed File System) ,⁶ 它们使集群能够以分布式算法处理超大规模数据集。Hadoop 还配套了若干实用组件,以增强存储、处理与分析海量数据的能力。

其中值得一提的是 Apache Hive 。⁷ Hive 构建于 Hadoop 之上,是面向存储于 HDFS 的大数据集的"类 SQL"数据仓库系统。Hadoop 在数据湖语境下的一大优势是对数据格式的灵活性 :不同于需要预定义模式的传统数据库,Hadoop + Hive 支持读时模式(schema-on-read) ------允许先以"无固定结构"的方式摄取与存放数据,等到读取时再定义模式。这种灵活性对处理多类型数据极为宝贵。关于 Hive 的更多内容见后文"Apache Hive"。

理解 Hadoop 对把握现代数据架构尤为关键,因为今天仍能看到许多 Hadoop 组件或理念 的延续。接下来我们概述最相关的基础:先讲 HDFS ,再到 MapReduce ,随后介绍 Hive ;我们也会讨论使用 HDFS 与 MapReduce 的局限;最后讨论 Apache Spark 的兴起,它是许多现代**湖仓(lakehouse)**架构的中坚。

Hadoop 分布式文件系统(HDFS)

HDFS 以其容错性处理海量数据 的能力著称。需要注意的是,HDFS 通过水平扩展 来扩容,⁸ 与依赖垂直扩展 的 RDBMS 形成对比,从而缓解负载问题并在一定程度上实现"计算与存储解耦"。

与数据仓库中的 RDBMS 不同,HDFS 的数据管理方式是将数据切分为较大的块(block) ,再在集群各节点间分布与副本冗余 。常见块大小为 128MB 或 256MB ,默认副本因子3 。因此,若数据在节点间未得到恰当的对齐与分布 ,HDFS 的读写 I/O 可能比较耗时。此外,处理这些文件也有挑战:过多的小文件 会导致作业任务过度切分,带来明显的开销。由于 Hadoop 针对大文件 优化,对数据进行逻辑分组有助于提升存储与处理效率。是的,在 Hadoop 上采用**(反范式化的)数据模型**通常更为可取。其数据分布机制很强大,但若管理不当也可能极其低效。

在 HDFS 中,数据块不可变 :你只能插入或追加 记录,而不能直接对数据做就地更新。这与许多数据仓库系统对单条变更(mutation)的处理不同。Hadoop 系统会先把所有变更写入不可变的预写日志(WAL) ,再由异步流程将其应用到数据文件。那么这对数据模型中的历史数据 意味着什么?前文在 Kimball 方法中提到缓慢变化维(SCD) :它们可选择性地保留属性的历史变化,允许在特定时间点查询。若想在 Hadoop 上实现类似能力,往往需要一种变通方案物理重建维表的新版本以包含全部历史变化------即重新装载全量数据并生成一张包含更新后的新表。此过程资源开销大、管理复杂。因此,在用 Hadoop 承载传统数据仓库负载时,必须充分评估这些影响。

从 HDFS 的存储机制过渡到数据处理,下面谈谈 MapReduce

MapReduce

MapReduce 是一种并行计算模型,用于在分布式集群上处理数据,多年来曾是 Hadoop 大数据处理的主引擎 。它通过 Map / Shuffle / Reduce 三个阶段执行作业:

  • Map 阶段
    将输入数据切分为更小的块,分布到集群各节点并行处理 。如果数据在节点间分布不均,部分节点会更快完成任务,从而拖累整体性能
  • Shuffle 阶段
    将 Map 的输出进行排序与分区 ,再传递到 Reduce。若输出数据量庞大且需要跨网络传输,此阶段会耗时较长
  • Reduce 阶段
    对经 Shuffle 的数据进行聚合与进一步处理 ,同样是并行执行。与 Map 类似,若 Reduce 任务分布不均,会导致部分节点先结束、整体作业变慢

可见,若数据在节点间分布不均 ,Map / Shuffle / Reduce 都可能引发性能问题。由于涉及跨网络传输 ,确保任务高效运行至关重要。尽管在最新的平台上 MapReduce 本身可能不再直接使用,但其思想与大数据计算范式 依然构成许多现代数据架构的基础。接下来,我们将继续介绍Apache Hive,它最初正是建立在 MapReduce 奠定的基础之上。

Apache Hive

Apache Hive 最初由 Facebook 开发,为 Hadoop 提供了一层 SQL 能力,使用户能用类 SQL 的 HiveQL 查询与分析存放在 Hadoop 上的大规模数据。Hive 以 MapReduce 作为底层执行引擎来处理查询并进行分析,数据存放在 HDFS 中。执行查询时,Hive 会将 HiveQL 翻译为 MapReduce 作业并在 Hadoop 集群上运行;这些作业从 HDFS 读数据、处理后再写回 HDFS------这一过程涉及大量的磁盘 I/O 与网络数据传输。

数据存储与查询方式 上,Hive 与传统数据仓库有显著差异。传统数仓通常将数据以专有格式 存储,并在其上直接执行 查询;而 Hive 将数据存于 HDFS,并通过 MapReduce 作业 来执行查询。此外,Hive 使用的文件格式为开源格式 (遵循开源许可证)。为更好地理解 Hive 如何存储与管理数据,下面先介绍外部表与内部表 的模式,再介绍 Hive Metastore

外部表与内部表(External and internal tables)

在 Apache Hive 中,外部表内部表(受管表)有重要区别。外部表指向 Hive 之外 的数据,通常是位于 HDFS 上的 CSVParquet 文件。对这类数据 Hive 不具备控制权 ,它只是提供文件级直连访问,便于对文件进行分析------例如,你可以把一个 CSV(逗号分隔值)文件"挂载"为外部表并直接查询。

NOTE

在 Hive 中删除外部表 只会移除元数据 ,底层数据文件仍会保留;而删除受管表 会同时删除表元数据与底层数据

与之相对,内部表(受管表)由 Hive 完全托管。这类表常使用列式存储格式 ,如 ORC(Optimized Row Columnar)Parquet ,它们在许多现代"奖章分层(Medallion)"架构中十分常见。列式格式对于包含聚合、过滤、排序的大数据分析查询尤其有利:它们显著减少 I/O 与内存装载量,并提供更好的压缩率,从而节省存储空间、降低大体量数据管理成本。

Hive Metastore

Hive 的关键组件之一是 Hive Metastore :一个集中式的元数据存储库,用于保存 HDFS 集群中表、列、分区 的元信息。元数据包括数据的模式(schema) 、在 HDFS 上的物理位置以及查询与处理所需的其他信息。该组件在当今许多 Medallion 架构中仍然存在。

借助 Metastore,Hive 允许在不预先强制定义模式 的情况下摄取数据;相反,会在读取数据时按需应用模式 ,这被称为 "读时模式(schema on read)" 。这与传统数据库普遍采用的 "写时模式(schema on write)" (写入时必须符合预定义模式)形成鲜明对比。

WARNING

"读时模式"在现代数据架构中依旧常见,但也常被误解。有人误以为有了读时模式就不需要数据建模 ------这是严重误区!若缺乏恰当的数据建模,数据将不完整或质量低下 ,多源数据的集成 也会变得困难,同时还会导致性能不佳 。读时模式有助于快速存放与探索原始数据 ,但数据质量、集成与性能保障仍必须到位。

Hive 及其元数据、HDFS 与 MapReduce 在早期也面临一些挑战。其一是海量小文件 的高效处理:在 HDFS 中,数据会在多台机器上分布与复制以增强并行处理能力。由于数据与元数据分离存储 ,每个文件无论大小都会至少占用一个默认块(block)大小的元数据开销。小文件(小于典型的 128 MB HDFS 块)会给 NameNode 带来过高压力。⁹ 例如,若块大小为 128 MB,1 TB 数据大约对应 8,000 个文件,元数据大约需要 1.6 MB ;但若把这 1 TB 数据存成 1 KB 的小文件,则元数据需要 200 GB ,系统负载增加 1,280 倍。若处理不当,此类问题会显著拉低整个数据湖的读取性能。

其二,早期版本的 Hive 不支持 ACID 事务与整表更新 ,可能导致数据库出现不一致 。好在这一问题在后续版本中已得到改进。关于这一点将在"开放表格式的兴起 "中再谈(涉及 Delta 表格式)。

其三,MapReduce 较慢 :在处理的每个阶段,数据都要落盘再读取 。这种频繁的磁盘寻道极其耗时,显著拖慢整体执行。这一性能瓶颈把我们引向了 Apache Spark,¹⁰ 它试图解决上述问题。

Spark 项目(Spark Project)

尽管 MapReduce 有其优点,但在大型应用中也暴露出一些低效之处。比如,典型的机器学习算法可能需要对同一数据集进行多次遍历 ,而每次遍历都必须写成一个独立的 MapReduce 作业 ;这些作业需要逐一在集群上启动,每次都要从头装载数据

为应对这些挑战,加州大学伯克利分校 AMPLab 的研究者们在 2009 年 发起研究项目,加速 Hadoop 体系中的处理作业。他们开发了一个内存计算 框架------Spark 。通过将数据存放在内存中,而非每一步都从磁盘读取,Spark 更高效地支持大规模数据处理。该团队还开发了 Shark ,¹¹ 即基于 Spark 的 SQL 扩展,使数据科学家与分析师能以更交互式 的方式使用 SQL。Shark 的架构基于 Hive:它将 Hive 生成的物理执行计划转换为内存程序 ,从而使 SQL 查询相对 Hive + MapReduce 可提速至 100 倍

随着 Spark 的演进,人们意识到引入新的 可大幅增强能力,于是项目开始采纳"标准库 "的路径。¹² 与此同时,团队逐步以 Spark SQL 取代 Shark;Spark SQL 通过使用 Hive Metastore保持与 Hive 的兼容

需要注意的是,Spark 的加速 有一定前提:它仍需从磁盘读取数据 才能把它放入内存,这不是瞬时完成 的。也就是说,数据写入 HDFS 后,还需要一个额外的装载过程 将其加载进 Spark 内存。至今如此:例如重启 Spark 集群 会丢失全部内存数据,必须重新加载才能恢复速度优势。对现代架构而言,这意味着资源可用之前通常存在一个启动期 ,¹³ 在此期间数据并未即时驻留于 Spark;只有当查询与/或缓存流程启动后,数据才会进入"可被快速使用"的状态。

关于 Spark 的讨论先告一段落;我们会在下一节讲到湖仓(lakehouse)架构 时再回到 Spark。下面来看数据湖的经验与演进

迈向未来的数据湖(Moving Forward with Data Lakes)

我们能从数据湖及其演进中学到什么?要点如下:

  • 由 Hadoop 驱动的数据湖 ,擅长以多种格式(结构化与非结构化)存放海量原始数据 ,并可为数据科学与机器学习 应用就绪;它们不受传统数仓的格式限制,依赖 Parquet开源格式 ,与众多工具、驱动与库高度互操作 。此外,外部表/受管表等核心概念在现代数据架构中依旧存在。
  • 然而,随着数据湖普及与广泛使用,组织也注意到一些挑战:摄取原始数据很容易 ,但将其转化为可交付业务价值 的形态却很复杂。传统数据湖在时延与查询性能 方面掣肘,需要一种不同的数据建模方法,才能真正发挥其分布式 与对多数据类型弹性处理的优势。
  • 传统数据湖还面临诸如小文件过多事务能力不足 等问题。因此,很多组织采用把数据回灌到传统数据仓库的"两层架构"模式:数据湖以 ML 友好格式存放数据,再将其子集加载进数仓。
  • 为应对这些挑战,业界正把"两层架构"融合为单一方案 :既具数据湖的可扩展性与灵活性 ,又具数据仓库的可靠性与性能 。要理解这一融合如何演进,就需要回顾湖仓(lakehouse)架构的历史与发展。

湖仓架构简史(A Brief History of Lakehouse Architecture)

前文我们回顾了数据仓库与数据湖的历史,现在来到数据架构演进的最后一部分:考察当今以湖仓(lakehouse)为基础、并采用 Delta Lake开源表格格式 的架构。为此,我们先看 Spark 在发布后的演进,再讨论 Databricks 的起源、其在数据领域的角色及与其他技术提供方的关系,最后回到奖章分层(Medallion)架构

Spark 的创始团队(Founders of Spark)

2013 年 ,Spark 项目已由来自 30 个组织的 100+ 位贡献者共同推动,声势大增。为确保其长期可持续厂商中立 ,团队决定将 Spark 以开源形式捐赠给 Apache 软件基金会 ,自此 Spark 成为 Apache Spark ,并升格为 Apache 顶级项目

同年,Spark 的创建者成立公司 Databricks ,以支持并商业化 Spark 的快速增长。Databricks 的目标是简化大数据处理,让数据工程师、数据科学家与业务分析师更易用。随后,Apache Spark 社区相继发布多个大版本:Spark 1.0(2014)Spark 2.0(2016)Spark 3.0(2020)Spark 4.0(2025) ,并持续通过新特性增强能力。

值得一提的是,Databricks 采取了与 Hadoop 竞争者不同的市场策略:与 ClouderaHortonworks 偏重本地部署 不同,Databricks 推出纯云 发行版 Databricks Cloud (当时甚至提供免费 Community Edition)。Databricks 先在 AWS 起步,随后支持 Microsoft AzureGoogle Cloud Platform2017 年 11 月 ,Databricks 通过集成成为 Azure 的一方托管服务(Azure Databricks)。随着云采用加速、存储与计算解耦 的云上方案流行,传统本地 Hadoop 部署式微。可以说,Databricks 的这一策略选择极为明智

这对 Hadoop 意味着什么?Hadoop 过时了吗? 。它仍活跃于云生态,只是形态发生了显著变化 :厂商以云对象存储 取代 HDFS 。对象存储将文件的数据块与元数据、唯一标识一起作为对象保存;这不同于 HDFS 将数据分块到不同节点、再由独立的元数据服务(如 NameNode)追踪位置的方式。

转向云对象存储带来多重优势:不仅整体上更低成本 以容纳海量数据,而且可高效扩展 至 PB 级。各大云厂商都提供此类服务,配有强健的 SLA跨地域复制 选项。比如 Microsoft 推出的 Azure Data Lake Storage ,在兼容 HDFS 接口 的同时,现代化 了底层存储架构。简言之:HDFS 接口仍在,底层存储已换代

Spark 也经历了类似演进,且主要受 Databricks 贡献驱动。如今 Spark 既可在虚拟机集群 上独立运行,也可在 Kubernetes 管理的容器环境中运行。这种灵活性意味着你不再被一个"单块"的 Hadoop 大集群束缚,而是可以按需创建多个 Spark 集群 ,各自拥有独立的计算配置与规模,同时共享同一层对象存储 ,让 Spark 既弹性动态

Databricks 在 Apache Spark 的路线图与开发上扮演主导力量 。其提供的托管平台 让用户无需学习复杂的集群管理或进行无休止的工程工作,即可通过友好界面直接受益;使用 Databricks 的公司也能及时享受其最新创新。

接下来,让我们把焦点转向当今的现代架构------由于开源表格格式标准 (如 HudiIcebergDelta Lake)的发展而取得长足进步。

开放表格式的兴起(Emergence of Open Table Formats)

鉴于在列式存储格式中对更强事务保证更优元数据处理更高数据完整性的迫切需求,一批项目相继出现并开源:

  • Apache Hudi(2017,Uber 发起) :简化在 Hadoop 兼容文件系统上管理大数据集,侧重高效 upsert删除增量处理 ;无缝对接主流存储,支持 Parquet/ORC
  • Apache Iceberg(2018,Netflix 开源) :为大规模分析系统解决性能与复杂度问题,引入改进的表格式以优化慢操作与易错流程,支持 Parquet/ORC/Avro
  • Delta Lake(2019,Databricks) :进一步解决传统数据湖中的事务缺失与一致性问题,引入 ACID 事务 、可扩展元数据、流批一体 ;通过模式约束与演进 保障数据完整性;底层仅用 Parquet ,默认压缩 Snappy

HUDI / ICEBERG / DELTA LAKE 近况
2024 年 ,Databricks 收购了支持 Apache Iceberg 生态的 Tabular ,目标是实现不同湖仓平台之间的兼容性 。短期内,Delta Lake 推出 UniForm :主要写入 Delta,同时异步生成 Iceberg 或 Hudi 的元数据。长期看,Databricks 致力于打造单一、开放、通用 的跨平台互操作标准,提供更连贯的管理体验。与此同时,Apache XTable (源自 Hudi 发起者)也提供在 Delta/Hudi/Iceberg 三者之间的单向真转换方案。

Delta Lake 通过事务日志(DeltaLog)实现 ACID:当用户对表执行插入/更新/删除等修改时,Delta 会将其拆解成离散步骤(若干动作),并以有序、原子 的提交(commit)记录在事务日志中。该日志默认存放于表 Parquet 文件目录下的 _delta_log/ 子目录。图 1-7 展示了 DeltaLog 的结构示例。

在 Delta Lake 中,每次提交都会写成一个 JSON 文件,从 000000.json 开始顺序递增。随着表被更新,Delta 保留所有历史版本 。¹⁴ 这就是所谓的 "时光回溯(time travel)" :可在任意时间点查看表的状态。例如,你可以回看一次更新前的表,或检视某一特定时刻的快照。更多细节可参考"Diving Into Delta Lake: Unpacking the Transaction Log"。

图 1-7 Delta Lake 的数据与事务日志组织示例

湖仓架构的兴起(The Rise of Lakehouse Architectures)

随着 Delta Lake 的发布,"湖仓架构 "这一概念开始流行。它融合了数据湖数据仓库 的优势,允许组织在统一的数据平台 上运行,且以开源软件为基础。虽然湖仓并不绑定任一特定技术,但最流行的实现多围绕 Apache Spark + Delta Lake :Spark 负责大数据计算 ,Delta Lake 提供开源存储层。图 1-8 概述了湖仓的典型形态。

图 1-8 典型湖仓架构(包含 Bronze / Silver / Gold 三层示意)

相较以往架构,湖仓的独特之处在于:在低成本云对象存储 之上同时提供 ACID 事务 ;并在性能上大幅优于传统数据湖 ,这在很大程度上得益于 Apache Spark 的创新。Databricks 首创并定位"lakehouse"这一产品空间,随后其他主流厂商很快跟进。以下为 截至 2025 年的生态概览:

  • Databricks
    强力拥护湖仓架构,深度整合 Delta Lake (ACID 事务、可扩展元数据),与 Apache Spark 高度契合,显著提升大数据处理与分析的性能与可靠性
  • Azure HDInsight
    微软的云上托管 Hadoop/Spark 服务,提供可扩展的计算环境;支持多种表格式,并与 Azure 其他服务集成以增强分析能力。
  • Azure Synapse Analytics
    将大数据与数据仓库融合为一体化分析服务;通过无服务器预配资源提供灵活查询,优化大规模数据管理与分析。
  • Microsoft Fabric
    SaaS 形态提供分析与数据平台,利用 SparkDelta Lake 及一整套服务,覆盖广泛的数据操作与分析场景。
  • Cloudera
    支持多种表格式与处理框架,强整合 Hadoop/Spark,为建设多样化湖仓架构提供灵活环境。
  • Dremio
    基于 Apache Arrow 强化跨语言的内存数据操作;擅长高效的数据湖直接查询与分析。
  • Starburst
    Trino(开源分布式 SQL 引擎)为核心,提供快速、可扩展的跨源分析;支持多种表格式并与湖仓技术无缝集成以提升查询性能。

除上述厂商外,AWS、GCP、Snowflake 等也开始在自家产品中引入"lakehouse"概念。这表明湖仓架构在数据管理行业中的认可度与采用率持续上升 。科技巨头正在融合数据湖与数据仓库的优点,打造更全面高效 的数据解决方案。随着更多组织寻求优化数据处理与分析能力,湖仓正成为首选架构之一,引领数据管理的未来。

最后,Databricks 与 Microsoft 共同倡导将奖章分层(Medallion)架构 作为基于 Spark + Delta Lake 的分层最佳实践。这也是本书的核心主题:该设计模式在湖仓中组织数据,目标是在数据沿着 Bronze → Silver → Gold 的层次推进时逐步提升结构与质量 。下一节我们将深入这些层在落地时面临的实践挑战 ;在回答这些问题后,本章将收束,并在第 2 章 探讨 Medallion 架构的基础,第 3 章给出设计模式的详细说明。

奖章分层架构及其实践挑战(Medallion Architecture and Its Practical Challenges)

"奖章分层(Medallion)架构"这一术语最早由 Databricks 提出,它并非对既有架构的简单演进,而是一种数据设计模式 :为在湖仓(lakehouse)中组织数据提供一种逻辑清晰、结构化的路径。该名称来源于三大分层------Bronze、Silver、Gold ,这是一组面向用户的管理标签,类似于在数据仓库或数据湖中对数据进行分层。数据从 Bronze 走向 Gold,不仅意味着数据质量 的提升,也意味着结构化程度与校验的增强。

尽管"Bronze=原始数据、Silver=清洗数据、Gold=可供消费的数据"这样的标签直观易懂,但缺乏可操作的实践指引 。更广泛地说,业界对各层的具体职责并无一致共识 ,且这些术语本身也不够精确。既然我们已经确认数据建模至关重要 ,就能看出:命名规范只能作为起点,真正的难点在于落地实践 ,以及理论指导与实际执行之间的差异------这正是本书要深入探讨的核心主题。

第 2 章 ,我们将回顾若干基础概念,帮助你在 Medallion 架构中穿行,包括着陆区、原始数据、批处理、以及 ETL 与编排工具。随后在第 3 章 ,我们将逐层深入讨论 Medallion 架构,对每一层展开细致剖析。通过这一系统性的审视,你将更清楚地理解数据如何在各层之间演进,以及在真实场景中有效应用该架构所面临的挑战与考量

结语(Conclusion)

我们从传统的数据仓库与 OLTP 系统谈起,随后转向 Hadoop 与数据湖的兴起,最终抵达创新的湖仓 模型。每一步演进都源自对前一代架构局限 的回应,尤其是在应对当代数据的规模、多样性与复杂度方面。

这种演进也改变了我们管理与控制 现代数据架构的方式。传统数据仓库在本地运行时,我们能直接变更硬件配置、网络与存储 ;而随着云计算崛起,业界转向全分布式与托管服务 :伸缩更容易,但对底层基础设施的可控性降低。在此背景下,正确的配置、分层与数据设计 尤为关键。正如前文所强调的,数据建模 在架构设计中始终是成功的基本前提;接下来的章节将对此展开更深入的论述。

另一项重要演进体现在业务响应速度 上:业务用户期望更快地交付新项目与洞察,这给现代数据架构的交付带来持续压力。许多组织未能认识到数据建模不可或缺 ;一些 Data Mesh 实践也常忽略这一点,¹⁵ 结果是分布式团队 反复造出略有差异且互不兼容 的模型,这些差异随后固化在分析模型、ETL 流水线、数据产品与应用代码里,使原本清晰显式的设计变得晦涩且割裂

Medallion 架构注意到了这些问题,但并不能单凭模式本身给出定论性的解法 。这一设计在落地中的实践表明:理论模型与真实世界的实现/案例之间存在缺口 。这也再次凸显:组织需要精确的数据建模与治理策略,并根据自身需求进行定制。

展望未来,数据架构师与工程师应当持续探索 这些模型,理解其细微之处 ,并审慎应用 ,以满足不断攀升的大数据环境需求。第 2 章 将详细梳理构建现代数据架构所需的前置条件 ,为深入到第 3 章的讨论------即对 Medallion 架构各层更细致的洞察------打下坚实基础。

相关推荐
智海观潮3 小时前
学好Spark必须要掌握的Scala技术点
大数据·spark·scala
数据智能老司机3 小时前
构建 Medallion 架构——深入解读Medallion架构
大数据·架构·数据分析
kebijuelun4 小时前
OpenAI 最新开源模型 gpt-oss 架构与训练解析
人工智能·gpt·语言模型·架构
●VON4 小时前
重生之我在大学自学鸿蒙开发第七天-《AI语音朗读》
学习·华为·云原生·架构·harmonyos
凯禾瑞华养老实训室4 小时前
智慧养老实训室建设指南:厂家的产品选型与应用建议
大数据·人工智能·ar·vr·虚拟仿真·智慧健康养老服务与管理
德昂信息dataondemand5 小时前
开好经营月会:如何把数据变成决策的利器?
大数据·人工智能·abi·经营月会
fakerth5 小时前
【OpenHarmony】存储管理服务模块架构
架构·操作系统·openharmony
ajax_beijing5 小时前
hadoop的三副本数据冗余策略
大数据·hadoop·分布式
失散135 小时前
分布式专题——46 ElasticSearch高级查询语法Query DSL实战
java·分布式·elasticsearch·架构