首页/数据/数据工程与 ETL 速查/Delta Lake 基础用法
管道基础52 条

Delta Lake 基础用法

Delta Lake 用事务日志(_delta_log)记录每次提交,提供 ACID、时间旅行与 MERGE 更新;Spark 上以路径或元数据表方式读写。

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 汇总文件;这类动作由写入方自动触发,但日志目录本身不宜被其他程序改动。

易错点

  • 直接删数据文件绕过事务日志会破坏表一致性,清理必须用 VACUUM
  • VACUUM 保留期设得过短,时间旅行与增量读会立刻失效
  • 把表当普通 Parquet 目录用其他工具追加文件,日志与文件集合对不上
  • MERGE 的连接条件不唯一,同一行被匹配多次导致结果依赖执行顺序
  • 长期不做 OPTIMIZE,小文件堆积让查询与增量读取都变慢

数据来源与参考

  • Delta Lake 官方文档:Concurrency Control、Time Travel、VACUUM
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌