14

数据湖与湖仓一体

现代数据架构

阅读量:3 · 预计 21 分钟读完

数据湖湖仓一体IcebergDelta Lake
关联层级:L7 应用抽象
阅读进度4%

第十四章 数据湖与湖仓一体 - 现代数据架构

导读

在过去十年中,企业数据的规模和多样性呈爆炸式增长。传统的数据仓库虽然提供了强大的查询能力,但在处理海量非结构化数据、支持多种计算引擎、以及成本控制方面面临挑战。与此同时,数据湖以其低成本、灵活性和开放性吸引了大量关注,但在查询性能、事务支持和数据治理方面存在不足。

湖仓一体(Lakehouse)应运而生,它结合了数据湖和数据仓库的优势——在数据湖的低成本开放存储之上,叠加数据仓库的 ACID 事务、高性能查询和数据治理能力。这一架构正在成为现代数据平台的标准范式。

本章将深入探讨数据湖的演进、开放表格式(Apache Iceberg、Apache Hudi、Delta Lake)的技术原理、湖仓一体的架构设计,以及现代数据栈的最佳实践。


核心概念详解

14.1 数据仓库的局限

14.1.1 传统数据仓库

传统数据仓库(如 Teradata、Oracle Exadata、Greenplum)是专为分析工作负载设计的系统。它们通常采用共享存储或共享 nothing 架构,提供强大的 SQL 查询能力和 ACID 事务支持。

传统数据仓库的特点:

  • 专有格式:数据以专有的列式格式存储,与特定的计算引擎绑定。
  • 紧耦合:计算和存储通常部署在同一组机器上,扩缩容需要同时调整。
  • 高成本:需要专用的硬件和软件许可,总体拥有成本高。
  • 封闭生态:只能使用厂商提供的工具和接口。

14.1.2 数据仓库面临的挑战

随着数据规模和多样性的增长,传统数据仓库面临以下挑战:

数据规模:

  • 数据量从 TB 级增长到 PB 甚至 EB 级。
  • 传统数据仓库的扩展成本随规模线性增长。

数据多样性:

  • 除了结构化数据,还需要处理半结构化(JSON、XML)和非结构化(图片、视频、文本)数据。
  • 传统数据仓库主要针对结构化数据优化。

计算多样性:

  • 除了 SQL 查询,还需要支持机器学习、流处理、图计算等多种计算引擎。
  • 传统数据仓库通常只支持 SQL。

成本压力:

  • 数据量增长但 IT 预算有限。
  • 需要更灵活的计费模式(按需付费 vs 预留资源)。

14.2 数据湖的兴起

14.2.1 数据湖的定义

数据湖(Data Lake)是一个集中式的数据存储,可以存储任意规模的结构化、半结构化和非结构化数据。

数据湖的核心特点:

  • 开放格式:数据以开放的格式存储(如 Parquet、ORC、CSV、JSON),不依赖特定的计算引擎。
  • 低成本存储:通常使用云对象存储(如 S3、GCS、Azure Blob),成本远低于传统数据仓库。
  • Schema-on-Read:数据写入时不强制 Schema,读取时才解析数据结构。
  • 多引擎支持:同一份数据可以被 SQL 引擎、流处理引擎、机器学习框架等多种计算引擎访问。

14.2.2 数据湖的架构

典型的数据湖架构:

存储层:

  • 云对象存储(S3、GCS、Azure Blob)或分布式文件系统(HDFS)。
  • 提供低成本、高持久性、高可用的数据存储。

数据格式:

  • 列式格式:Parquet、ORC(适合分析查询)。
  • 行式格式:CSV、JSON、Avro(适合流处理和灵活 Schema)。

计算层:

  • SQL 引擎:Presto/Trino、Spark SQL、Hive。
  • 流处理:Spark Streaming、Flink。
  • 机器学习:Spark MLlib、TensorFlow、PyTorch。

元数据层:

  • 数据目录(Data Catalog):如 AWS Glue、Apache Atlas。
  • 提供数据的发现、搜索和治理。

14.2.3 数据湖的问题

虽然数据湖提供了灵活性和低成本,但也引入了新的问题:

缺乏事务支持:

  • 原始的数据湖不支持 ACID 事务。
  • 并发读写可能导致数据不一致。
  • 部分写入失败可能导致脏数据。

数据质量差:

  • Schema-on-Read 意味着数据写入时不验证,可能导致"数据沼泽"。
  • 缺乏数据验证和治理机制。

查询性能不稳定:

  • 没有索引和统计信息优化,查询性能不可预测。
  • 小文件问题:大量小文件导致查询性能下降。

缺乏更新和删除:

  • 对象存储通常只支持追加写入,不支持原地更新和删除。
  • 数据修正(如 GDPR 的"被遗忘权")困难。

14.3 开放表格式

为了解决数据湖的问题,业界开发了多种开放表格式(Open Table Format),在数据湖之上添加 ACID 事务、索引、更新/删除等能力。

14.3.1 Apache Iceberg

Apache Iceberg是 Netflix 开源的表格式,现在是 Apache 顶级项目。

Iceberg 的核心设计:

隐藏分区(Hidden Partitioning):

  • 分区策略由表的元数据管理,用户不需要在查询中指定分区条件。
  • 查询优化器自动利用分区信息跳过不相关的数据(分区裁剪)。
  • 支持按值分区(如按日期)、按桶分区(如按 ID 哈希)。

Schema 演化:

  • 支持安全的 Schema 变更:添加列、删除列、重命名列、修改列类型。
  • Schema 变更不需要重写数据。
  • 通过列 ID(而非列名)追踪列,保证 Schema 演化的安全性。

ACID 事务:

  • 使用乐观并发控制,支持并发写入。
  • 写入时创建新的快照(Snapshot),读取时选择一个快照。
  • 快照之间通过元数据链连接,支持时间旅行。

文件格式:

  • 默认使用 Parquet 作为数据文件格式。
  • 也支持 ORC 和 Avro。

索引:

  • 支持 Min/Max 索引:每个数据文件记录每列的最小值和最大值。
  • 查询时根据过滤条件跳过不相关的文件(文件裁剪)。
  • 支持 Bloom Filter 索引(实验性)。

14.3.2 Apache Hudi

Apache Hudi(Hadoop Updates and Incrementals)由 Uber 开发,专注于支持高效的更新和增量处理。

Hudi 的核心特性:

两种表类型:

  • Copy-on-Write(CoW):写入时重写整个数据文件。读取性能高,写入放大。
  • Merge-on-Read(MoR):写入时只写入增量日志,读取时合并基础数据和增量。写入性能高,读取时需要合并。

时间旅行:

  • 支持按时间点查询数据。
  • 每个提交创建一个新版本,可以回滚到任意版本。

增量查询:

  • 支持查询自某个时间点以来的增量数据。
  • 适合增量 ETL 和流式消费。

索引:

  • 支持 Bloom Filter 索引,加速点查。
  • 支持 Record Level Index,加速更新操作。

14.3.3 Delta Lake

Delta Lake由 Databricks 开发,是 Spark 生态系统中的表格式。

Delta Lake 的核心特性:

ACID 事务:

  • 使用乐观并发控制。
  • 支持 Serializable 隔离级别。

Schema 强制:

  • 写入时验证 Schema,防止无效数据写入。
  • 支持 Schema 演化(添加列、覆盖 Schema)。

时间旅行:

  • 支持按版本号或时间戳查询历史数据。
  • 支持数据回滚。

数据清理:

  • VACUUM 命令清理旧版本的数据文件。
  • 可配置保留时间(默认 7 天)。

统一批处理和流处理:

  • Delta 表可以作为批处理的源/目标,也可以作为流处理的源/汇。
  • 流处理使用 readStream 和 writeStream API。

14.3.4 三种格式对比

特性IcebergHudiDelta Lake
更新模式CoWCoW + MoRCoW
流式写入支持原生支持支持
增量查询支持原生支持支持
Schema 演化安全支持支持
时间旅行支持支持支持
引擎支持多引擎Spark 为主Spark 为主
社区ApacheApacheDatabricks 主导

14.4 湖仓一体架构

14.4.1 湖仓一体的定义

湖仓一体(Lakehouse)是在数据湖的低成本开放存储之上,叠加数据仓库的管理和性能特性的架构。

湖仓一体的核心特征:

  • 开放存储:数据以开放格式存储在对象存储中。
  • ACID 事务:通过开放表格式提供事务支持。
  • 高性能查询:通过索引、缓存、查询优化提供接近数据仓库的查询性能。
  • 数据治理:通过数据目录、血缘追踪、访问控制提供治理能力。
  • 多引擎支持:同一份数据可以被多种计算引擎访问。

14.4.2 湖仓一体的架构

典型的湖仓一体架构包含以下层:

原始数据层(Bronze / Raw):

  • 原始数据直接写入数据湖,保持原始格式。
  • 支持数据回溯和审计。

清洗数据层(Silver / Cleaned):

  • 对原始数据进行清洗、验证、标准化。
  • 使用开放表格式(Iceberg/Hudi/Delta)存储,提供 ACID 事务。
  • 支持更新和删除操作。

聚合数据层(Gold / Curated):

  • 针对业务查询优化的数据视图。
  • 预聚合、预计算的结果。
  • 使用列式格式存储,优化查询性能。

计算层:

  • SQL 引擎:Trino、Spark SQL。
  • 流处理:Flink、Spark Streaming。
  • 机器学习:Spark MLlib、Python 生态。

治理层:

  • 数据目录:Apache Atlas、AWS Glue、DataHub。
  • 数据血缘:追踪数据的来源和转换。
  • 访问控制:基于角色的数据访问控制。

14.4.3 湖仓一体的优势

相比纯数据湖或纯数据仓库,湖仓一体具有以下优势:

成本效益:

  • 使用低成本的对象存储,存储成本远低于数据仓库。
  • 计算和存储分离,可以独立扩展。
  • 按需使用计算资源,避免预留成本。

灵活性:

  • 支持多种数据格式和计算引擎。
  • 数据不被锁定在特定系统中。
  • 可以根据需求选择最合适的计算引擎。

可靠性:

  • ACID 事务保证数据一致性。
  • 时间旅行支持数据回溯和审计。
  • Schema 强制保证数据质量。

性能:

  • 通过索引、缓存、分区裁剪优化查询性能。
  • 列式格式提供高压缩比和向量化执行。
  • 接近传统数据仓库的查询性能。

14.5 现代数据栈

14.5.1 数据集成(Data Integration)

现代数据栈的数据集成工具:

ETL 工具:

  • Apache Spark:分布式数据处理引擎,支持批处理和流处理。
  • Apache Flink:流处理引擎,支持事件驱动的数据处理。
  • dbt(Data Build Tool):SQL-first 的数据转换工具,在数据仓库内执行转换。

ELT 工具:

  • Fivetran:自动化的数据管道,将 SaaS 数据同步到数据仓库。
  • Airbyte:开源的数据集成平台,支持 300+ 数据源。
  • Airflow / Dagster / Prefect:工作流编排工具。

CDC 工具:

  • Debezium:开源的 CDC 平台,支持多种数据库。
  • AWS DMS:AWS 的数据迁移服务。

14.5.2 数据质量与治理

数据质量:

  • Great Expectations:开源的数据质量框架。
  • Soda:数据质量监控平台。
  • Monte Carlo:数据可观测性平台。

数据治理:

  • Apache Atlas:开源的数据治理和元数据管理。
  • DataHub(LinkedIn):开源的元数据平台。
  • Collibra:商业数据治理平台。

数据安全:

  • 行级安全(Row-Level Security):根据用户角色控制数据访问。
  • 列级安全(Column-Level Security):控制敏感列的访问。
  • 数据脱敏:对敏感数据进行脱敏处理。

14.5.3 数据服务(Data as a Service)

现代数据栈趋向于将数据作为服务提供:

数据产品(Data Product):

  • 将数据组织为可发现、可信赖、自描述的产品。
  • 每个数据产品有明确的 owner、SLA、文档。
  • 数据消费者通过标准接口访问数据产品。

数据网格(Data Mesh):

  • 去中心化的数据架构,每个业务领域负责自己的数据产品。
  • 数据平台团队提供基础设施和标准。
  • 领域团队负责数据的质量、治理和服务。

重要知识点

知识点 1:开放表格式的元数据管理

开放表格式的核心是元数据管理。元数据包括:

表元数据:

  • 表的 Schema(列名、类型)。
  • 分区规范。
  • 表属性(如压缩格式、保留策略)。

快照元数据:

  • 每个快照记录表的完整状态。
  • 包含数据文件列表、统计信息。
  • 快照之间通过父指针链接,形成版本历史。

文件元数据:

  • 每个数据文件的路径、大小、行数。
  • 每列的统计信息(min、max、null count)。
  • 分区值。

元数据的存储:

  • Iceberg:使用 JSON 或 Avro 格式的元数据文件,存储在对象存储中。
  • Hudi:使用 Hoodie 元数据表,存储在对象存储中。
  • Delta Lake:使用 JSON 格式的日志文件(_delta_log),存储在对象存储中。

知识点 2:文件布局优化

数据湖中的文件布局对查询性能有重大影响。

小文件问题:

  • 大量小文件导致查询时需要打开大量文件,元数据开销大。
  • 解决方案:定期合并小文件(Compaction)。

数据倾斜:

  • 某些分区的数据量远大于其他分区。
  • 解决方案:调整分区策略,使用更细粒度的分区。

Z-Order 排序:

  • 将数据按多个列排序,使得相关数据在物理上相邻。
  • 查询时可以根据过滤条件跳过不相关的数据块。
  • Delta Lake 和 Databricks 支持 Z-Order 优化。

缓存和索引:

  • 使用本地 SSD 缓存热数据。
  • 使用 Bloom Filter、Min/Max 索引加速过滤。

知识点 3:数据湖的查询引擎

数据湖的查询引擎需要理解开放表格式的元数据:

Trino(Presto):

  • 支持 Iceberg、Delta Lake、Hudi 的连接器。
  • 提供高性能的交互式查询。
  • 支持联邦查询(跨多个数据源)。

Spark SQL:

  • 原生支持 Delta Lake,通过连接器支持 Iceberg 和 Hudi。
  • 适合大规模批处理和 ETL。

StarRocks / Apache Doris:

  • 支持直接查询 Iceberg 表。
  • 提供高性能的 OLAP 查询。

Apache Druid:

  • 支持从数据湖摄入数据。
  • 提供实时分析能力。

知识点 4:数据湖的成本优化

数据湖的成本优化策略:

存储分层:

  • 热数据:标准存储(如 S3 Standard)。
  • 温数据:低频存储(如 S3 Standard-IA)。
  • 冷数据:归档存储(如 S3 Glacier)。
  • 使用生命周期策略自动迁移。

数据压缩:

  • 使用高效的压缩算法(如 Zstd、Snappy)。
  • 列式格式本身提供高压缩比。

数据清理:

  • 定期清理过期数据和旧版本。
  • 使用 VACUUM 命令清理 Delta Lake 的旧版本。

计算优化:

  • 使用 Spot 实例降低计算成本。
  • 自动扩缩容,避免闲置资源。
  • 查询优化:分区裁剪、文件裁剪、谓词下推。

常见误区

误区 1:"数据湖可以完全替代数据仓库"

纠正:数据湖和数据仓库有不同的适用场景。数据湖适合大规模、多格式的数据存储和多引擎处理;数据仓库适合高性能的 SQL 查询和强一致性保证。湖仓一体结合了两者的优势,但不是简单的替代关系。

误区 2:"开放表格式的性能不如专有数据仓库"

纠正:现代开放表格式(Iceberg、Delta Lake)通过索引、缓存、查询优化,已经可以提供接近专有数据仓库的查询性能。Trino、StarRocks 等引擎对开放表格式的支持越来越好,性能差距在缩小。

误区 3:"数据湖不需要数据治理"

纠正:数据湖的灵活性使得数据治理更加重要。没有治理的数据湖很容易变成"数据沼泽"——数据质量差、难以发现、难以信任。需要数据目录、血缘追踪、Schema 强制、访问控制等治理机制。

误区 4:"所有数据都应该放在数据湖中"

纠正:不是所有数据都适合放在数据湖中。高频访问的热数据、需要强一致性的数据、需要低延迟查询的数据,可能更适合放在专门的数据库或缓存中。数据湖适合存储大规模的历史数据、原始数据和中间数据。

误区 5:"湖仓一体是一种具体的产品"

纠正:湖仓一体是一种架构理念,而非具体的产品。可以通过多种产品组合实现湖仓一体——如 S3 + Iceberg + Trino + dbt + DataHub。选择具体的产品需要根据团队技能、业务需求和生态系统来决定。


实践应用

实践 1:设计湖仓一体架构

设计湖仓一体架构的步骤:

选择存储层:云对象存储(S3、GCS)或 HDFS。

选择表格式:根据引擎支持和团队技能选择 Iceberg、Hudi 或 Delta Lake。

设计数据分层:Bronze(原始)→ Silver(清洗)→ Gold(聚合)。

选择计算引擎:根据查询需求选择 Trino、Spark SQL 等。

设计数据管道:使用 Airflow、dbt 等工具编排 ETL 流程。

实施数据治理:使用数据目录、血缘追踪、访问控制。

实践 2:选择开放表格式

选择开放表格式的决策因素:

因素IcebergHudiDelta Lake
引擎多样性多引擎Spark 为主Spark 为主
更新频率中高中
流式写入支持原生支持支持
社区活跃度高中高
学习曲线中中低(Spark 用户)

实践 3:数据湖性能优化

优化数据湖查询性能的策略:

分区策略:根据查询模式选择合适的分区键和粒度。

文件大小:保持数据文件在 128MB-1GB 之间,避免小文件。

压缩格式:使用 Zstd 或 Snappy 压缩,平衡压缩比和速度。

排序优化:使用 Z-Order 或 Range 排序,加速过滤。

缓存:使用本地 SSD 缓存热数据。

索引:使用 Min/Max 索引和 Bloom Filter 加速过滤。

实践 4:数据湖成本管理

管理数据湖成本的策略:

存储分层:自动将冷数据迁移到低成本存储。

数据保留:设置数据保留策略,定期清理过期数据。

压缩:使用高效压缩减少存储空间。

计算优化:使用 Spot 实例、自动扩缩容。

查询优化:分区裁剪、文件裁剪、谓词下推减少扫描数据量。

监控:监控存储和计算成本,设置预算告警。


本章小结

本章深入探讨了数据湖与湖仓一体的核心概念和实践:

数据仓库的局限:

- 传统数据仓库在规模、多样性、成本和开放性方面面临挑战。

- 需要新的架构来应对现代数据的需求。

数据湖的兴起与问题:

- 数据湖提供低成本、灵活、开放的数据存储。

- 但缺乏事务支持、数据质量差、查询性能不稳定。

开放表格式:

- Iceberg:隐藏分区、安全 Schema 演化、多引擎支持。

- Hudi:高效的更新和增量处理、流式写入。

- Delta Lake:ACID 事务、Schema 强制、时间旅行。

- 在数据湖之上提供事务、索引、更新/删除等能力。

湖仓一体架构:

- 结合数据湖的低成本和数据仓库的管理/性能特性。

- 数据分层:Bronze → Silver → Gold。

- 多引擎支持、开放格式、ACID 事务。

现代数据栈:

- 数据集成:ETL/ELT 工具、CDC 工具。

- 数据治理:数据目录、血缘追踪、访问控制。

- 数据服务:数据产品、数据网格。

湖仓一体正在成为现代数据平台的标准架构。它通过开放表格式在数据湖之上提供数据仓库的能力,兼顾了灵活性、性能和成本。理解数据湖、开放表格式和湖仓一体的概念,对于构建现代化数据平台至关重要。

在选择开放表格式时,需要综合考虑团队的技术栈、引擎兼容性和社区活跃度。如果团队以 Spark 为核心计算引擎,Delta Lake 是一个自然的选择;如果需要多引擎支持(如 Trino、Spark、Flink 同时访问),Apache Iceberg 可能是更好的选择;如果应用场景涉及高频的数据更新和增量处理,Apache Hudi 值得重点考虑。无论选择哪种格式,关键是要确保数据格式的开放性——避免被单一供应商锁定,保持未来切换引擎和工具的灵活性。

湖仓一体的成功实施还需要关注数据治理和组织协作。技术架构只是基础,真正的挑战在于建立清晰的数据所有权、质量标准和服务级别协议。数据平台团队需要提供易用的工具和清晰的文档,降低领域团队发布高质量数据产品的门槛。只有技术和组织双管齐下,湖仓一体才能真正发挥其价值。

从技术选型的角度来看,湖仓一体的实施应该遵循渐进式的策略。不必一开始就追求完美的架构设计,而是从最紧迫的业务需求出发,逐步构建和完善数据平台。例如,可以先将现有的数据仓库数据迁移到开放格式(如 Parquet),建立基础的数据湖存储层;然后引入开放表格式(如 Iceberg),添加事务支持和 Schema 演化能力;最后根据查询需求,逐步引入专门的计算引擎和优化策略。这种渐进式的方法可以降低实施风险,同时在每个阶段都能交付可衡量的业务价值。此外,在迁移过程中应该特别注意保持向后兼容——确保现有的报表和分析工具在架构升级后仍然可以正常工作,避免对业务造成中断。