2. Lakehouse 架构基础:数据湖与数据仓库的区别、核心组件与 Delta Lake 简介
好,我们直接进入正题。这一章,我想跟你聊聊 Lakehouse 的底层逻辑。很多同学刚接触这个概念时,容易把它想得太玄乎。其实说白了,Lakehouse 就是想把数据湖的便宜大碗,和数据仓库的严谨可靠,给揉到一起。
我最早做数据平台的时候,经历过纯 Hive 数仓的臃肿,也踩过纯数据湖(比如 S3 + Spark)的坑——数据写进去容易,想做到 ACID 事务?难如登天。后来 Databricks 提出 Lakehouse 这个概念,我第一反应是:嗯,这才是生产环境该有的样子。
2.1 数据湖 vs 数据仓库:核心差异
我们先看一张对比表,把这两个东西掰开揉碎。
| 维度 | 数据仓库 (Data Warehouse) | 数据湖 (Data Lake) |
|---|---|---|
| 数据形态 | 结构化,Schema on Write | 结构化/半结构化/非结构化,Schema on Read |
| 存储成本 | 高(专用硬件/格式) | 低(廉价对象存储) |
| 事务支持 | 强 ACID | 弱或无(传统方案) |
| 数据质量 | 高(ETL 清洗后入仓) | 低(原始数据直接落盘) |
| 典型场景 | BI 报表、固定维度分析 | 机器学习、数据探索、日志归档 |
| 扩展性 | 垂直扩展为主,成本高 | 水平扩展,弹性好 |
我的经验之谈: 在风控场景里,数据湖适合存原始埋点、全量日志;数据仓库适合存经过清洗的标签宽表、交易流水。但如果你只有数据湖,做回溯分析时经常遇到“读脏数据”的问题——这就是为什么我们需要 Lakehouse。
2.2 Lakehouse 核心组件
一个标准的 Lakehouse 架构,我习惯把它拆成四层。你想想看,每一层解决一个核心痛点:
- 存储层:基于廉价对象存储(如 S3、OSS、HDFS)。存的是 Parquet、ORC 这类列式文件。
- 表格式层:这是 Lakehouse 的灵魂。Delta Lake、Apache Iceberg、Apache Hudi 都属于这一层。它们给底层文件加了一层“元数据事务日志”。
- 计算引擎层:Spark、Flink、Presto/Trino。负责读取表格式层暴露的“表”,执行 SQL 或 DataFrame 操作。
- 目录与权限层:Hive Metastore、Unity Catalog(Databricks)、AWS Glue Catalog。管理表结构、分区、权限。
我画了一张架构图,帮你把这几层的关系理清楚。
避坑指南: 我曾经在一个风控项目中,直接拿 Spark 写 Parquet 文件到 S3,没有用任何表格式。结果做数据回溯时,发现部分文件被覆盖了,导致历史报表对不上账。后来切到 Delta Lake,才彻底解决了这个问题。所以,表格式层不是可选项,是必选项。
2.3 Delta Lake 简介
在众多表格式中,Delta Lake 是我用得最多的一个。为什么?因为它跟 Spark 的集成最自然,而且它的核心设计非常优雅——事务日志 (Transaction Log)。
Delta Lake 本质上是一个 ACID 事务层,跑在 Parquet 文件之上。它把每一次对表的写操作(INSERT、UPDATE、DELETE、MERGE)都记录在一个 JSON 格式的日志里。这个日志存在 _delta_log/ 目录下。
我举个例子,你一看就明白:
-- 创建一个 Delta 表
CREATE TABLE risk_events (
event_id STRING,
user_id STRING,
event_type STRING,
event_time TIMESTAMP,
risk_score DOUBLE
) USING DELTA
LOCATION 's3://my-bucket/delta/risk_events/';
-- 插入一条数据
INSERT INTO risk_events VALUES
('evt_001', 'user_123', 'login', '2024-01-15 10:00:00', 0.85);
-- 查看事务日志(实际是文件)
-- _delta_log/00000000000000000000.json
-- 内容类似:
-- {"commitInfo":{"timestamp":1705300000000,"operation":"WRITE",...}}
-- {"add":{"path":"part-00000-xxx.snappy.parquet","size":1234,...}}
Delta Lake 的核心能力:
- ACID 事务:并发读写不冲突,不会读到半截数据。
- Schema 演进:可以动态加列,不用重建表。我在风控场景里经常遇到埋点字段临时增加,Delta Lake 直接
ALTER TABLE ADD COLUMNS搞定。 - 时间旅行 (Time Travel):可以查询任意历史版本的数据。比如你想看三天前的表状态,直接
SELECT * FROM risk_events VERSION AS OF 123。 - 数据版本控制:每次写操作都生成一个新版本,旧版本不会被立即删除,方便回滚。
注意: Delta Lake 的 VACUUM 命令会清理旧版本文件。如果你需要保留历史数据做审计,记得调大 delta.deletedFileRetentionDuration 配置,默认是 7 天。我建议风控场景至少保留 30 天。
2.4 为什么风控场景需要 Lakehouse?
你想想看,风控数据有几个特点:
- 数据量大:每天几十亿条埋点,全量存成本高。
- 需要回溯:经常要查“三天前某个用户的行为序列”,数据湖的 Schema on Read 正好合适。
- 需要事务:跑批任务时,如果中间失败,不能留半截数据。Delta Lake 的 ACID 保证了这个。
- 需要 Schema 灵活:业务规则经常变,字段说加就加。Lakehouse 的 Schema 演进能力完美匹配。
我记得有一次,业务方要求紧急上线一个“设备指纹”字段。如果是传统数仓,得先改 DDL、重建表、重跑历史数据,至少折腾半天。但在 Lakehouse 上,我直接 ALTER TABLE risk_events ADD COLUMNS (device_fingerprint STRING),然后新数据就带上了这个字段,旧数据自动补 NULL。整个过程不到 5 分钟。
这就是 Lakehouse 的魅力——它不逼你在“灵活”和“可靠”之间二选一。