Delta Lake 是什么
Delta Lake 在 Parquet 数据文件之外维护一个事务日志目录 _delta_log,每次写入都作为一个版本提交进去。有了这层日志,目录里的文件集合就变成一张有事务语义的表:支持并发写入、MERGE 更新、按版本读取历史数据。它最常见的落点是 Spark 的数据湖表,路径下的数据文件仍可被其他工具读取,但增量与版本信息依赖日志。
基本信息
| 核心结构 | JSON 事务日志 + 数据文件,按版本提交 |
|---|---|
| 关键能力 | MERGE upsert、时间旅行、schema 约束 |
| 维护动作 | 小文件合并、历史清理(VACUUM) |
| 默认保留 | VACUUM 保留期默认 7 天,可显式指定 |
| 典型引擎 | Spark(含 Spark SQL 与 DataFrame API) |
MERGE 与时间旅行(Spark SQL)
MERGE 与时间旅行(Spark SQL)
MERGE INTO delta.`/data/orders` AS t
USING updates AS s ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
-- 查询某个历史版本(VERSION AS OF 与 TIMESTAMP AS OF 二选一)
SELECT * FROM delta.`/data/orders` VERSION AS OF 12;
-- 合并小文件后清理无引用文件
OPTIMIZE delta.`/data/orders`;
VACUUM delta.`/data/orders` RETAIN 168 HOURS;典型使用场景
- 增量 upsert:用 MERGE 把上游变更合并进目标表而不整表重写
- 问题定位:按版本或时间戳读历史快照,确认数据何时被改错
- 流式接入:流任务持续写入,日志保证提交的原子性
- 误操作恢复:结合版本回滚到变更前的状态
- 小文件治理:用 OPTIMIZE 合并文件,再清理过期版本释放空间
常见操作读法
| 操作 | 作用 | 注意 |
|---|---|---|
| MERGE INTO | 按条件更新或插入 | 连接键要能唯一确定行,否则行为不确定 |
| VERSION AS OF | 读指定版本 | 版本被 VACUUM 清理后无法再读 |
| TIMESTAMP AS OF | 读指定时间点 | 时间点解析依赖日志保留范围 |
| OPTIMIZE | 合并小文件 | 会重写数据文件,需要额外 IO |
| VACUUM | 物理删除过期文件 | 保留期要覆盖最长查询与回滚窗口 |
VACUUM 会物理删除保留期外文件,正在读取的旧版本会失败;保留期要覆盖最长查询与回滚窗口。
事务日志会随提交次数增长,Delta 通过周期性 checkpoint 把日志压缩成 Parquet 汇总文件;这类动作由写入方自动触发,但日志目录本身不宜被其他程序改动。