DuckLake 湖仓表格式横评:8.2ms 恒定 commit 零 manifest——本机复测 DuckLake v1.0 vs Iceberg 1.12 vs Delta 4.4,SQL catalog 赢在小团队场景

61次阅读
DuckLake 湖仓表格式横评:8.2ms 恒定 commit 零 manifest——本机复测 DuckLake v1.0 vs Iceberg 1.12 vs Delta 4.4,SQL catalog 赢在小团队场景

一句话钩子:DuckLake 3,341★ · Iceberg 9,385★ · Delta 9,064★ ——「表格式战争已结束,表格式本身没有」。2026 年 4 月 DuckLake 1.0 把湖仓元数据塞进一条 SQL 事务,半年后本机复测:200 次小 commit 恒定 8.2ms、零 parquet 文件,catalog 仅 176KB——hikmah 基准的「4-8ms 恒定」在本机复现。Iceberg 赢在广度,Delta 赢在 Databricks 纵深,DuckLake 赢在「小团队不想要第二个基础设施」。


写在前面:战争结束了,分化刚开始

湖仓表格式(table format)之争的格局在 2026 年有了公论:Apache Iceberg 赢下了「跨引擎中立格式」的位置——五大引擎读写支持最广、三大云的托管服务全部押注;Delta Lake 守住 Databricks/Spark 纵深,靠 UniForm 向 Iceberg 世界递橄榄枝;Hudi 退守「低延迟 upsert + 索引」的利基;Paimon 在阿里系流式场景立足。

战争结束了,但「选哪个」变得更难了——因为 第四个玩家带着完全不同的架构假设入场 :DuckLake(DuckDB 团队 出品,v1.0 2026-04-13)把湖仓元数据从「一堆文件」搬进「一条 SQL 事务」。它赌的不是「更快的 Iceberg」,而是「你根本不需要 Iceberg 的那套机器」。

本篇做了别人没做的事:在本机复测 DuckLake 的 commit 基准 —— 上一盘 转述过 hikmah 的「50/500-commit 恒定 4-8ms、零文件」数字,复测结论:量级复现成功(8.2ms 恒定、零 parquet 文件),实验设计差异一并公开。

一、四种格式,一张表看清

维度 DuckLake v1.0 Iceberg 1.12.0 Delta Lake 4.4.1 Hudi 1.2.1
Stars 3,341 9,385 9,064 ~6.1K
出品 DuckDB 团队(基金会,见前篇) Apache 顶级 LF AI & Data(Databricks 主导) Apache
元数据存放 ACID SQL 数据库(Postgres/SQLite/duckdb 文件) manifest/manifest-list 文件树 + catalog _delta_log JSON 事务日志 时间线文件 + 索引
commit 机制 一次 SQL 事务 OCONcurrency 并发写文件 + catalog 提交 文件追加日志 时间线 instant
写放大 零 manifest(内联进 catalog) manifest 雪崩风险,需 compaction log 文件累积,需 checkpoint 索引维护成本
引擎广度 DuckDB 系(另有 Spark/Trino/DataFusion/Pandas 客户端,年轻) 最广(Spark/Trino/Flink/Snowflake/BigQuery/ClickHouse 全覆盖) Spark 原生 + UniForm 双发布 Spark/Flink
强项场景 高频小写入、跨表事务、少运维 多引擎共享表、分区演化、分支 /tag Databricks/Spark 深度用户 低延迟 upsert、CDC
风险 引擎绑定 DuckDB 系、格式年轻 小文件 /manifest 运维复杂度 生态绑定 Databricks 社区声量下降
license MIT Apache-2.0 Apache-2.0 Apache-2.0

一句话结论先行:「多引擎共享 + 平台团队」→ Iceberg;「Databricks/Spark 深度用户」→ Delta;「DuckDB 系 + 高频小写入 + 讨厌运维」→ DuckLake;「upsert/CDC 密集」→ Hudi。

二、本机实测:DuckLake 的 commit 基准复测

环境:Ubuntu,Python 3.12,pip install duckdb==2.0.0,INSTALL ducklake; LOAD ducklake,catalog 用 SQLite,存储本地目录。

实验 1:默认配置 200 连续小 commit

ATTACH 'ducklake:sqlite:/tmp/dl66c/cat1.db' AS d1 (DATA_PATH '/tmp/dl66c/data1')
-- 200 次 INSERT(每次自动提交 = 一次 commit)

结果:8.2 ms/commit,全程零 parquet 文件落盘,catalog.db 仅 176KB。

这就是 DuckLake 的灵魂设计——数据内联(data inlining):小写入(默认阈值 10 行以下,v1.0 起)不写 parquet 文件,直接进 catalog 的 SQL 表;只有数据攒大或显式 flush 才落文件。200 次 commit 的元数据(202 个 snapshots 全部可查)挤在 176KB 的 SQLite 里。

实验 2:强制落盘对照(显式 CHECKPOINT 每次执行)

for i in range(500):
    INSERT ...; CHECKPOINT   -- 每次 commit 强制落 parquet

结果:51 ms/commit,每 commit 产生 2 个 parquet 文件,500 次落了 999 个文件。

实验 3:两组对照读出的真相

写法 ms/commit 文件增长 解释
默认(内联开) 8.2(恒定) 0 文件 小写入进 catalog,纯 SQL 事务成本
显式 CHECKPOINT 51 2 文件 / 次 内联被绕过,每次真写 parquet+ 元数据

三条结论:

  1. 「恒定 4-8ms、零文件」在本机复现成功 (hikmah 口径 4-8ms,本机 8.2ms,同量级)——DuckLake 的 commit 成本是小 SQL 事务的成本, 不随 commit 数增长。对比 hikmah 测的 Iceberg 500 commits 从 9ms 涨到 202ms:那是 manifest 文件树 grew 的问题,机制层面 Iceberg 无法避免(本机未装 Spark/Iceberg 环境复测,此对照标「转述 + 机制推导」,Iceberg 同场景数字以官方为准)。
  2. 「零文件」是有条件的 ——条件就是数据内联。绕过内联(显式 flush/checkpoint),DuckLake 一样出现文件增长(51ms、2 文件 /commit)。选型时问清楚自己的写入模式: 高频小 append → 内联红利吃满;大批量写 → 内联无意义,DuckLake 相对 Iceberg 的优势收窄到「运维简单」。
  3. 时间旅行元数据完整:200 次 commit 后 ducklake_snapshots() 列出全部 202 个快照——小写入没有牺牲版本链。

复测的方法论注记 (为什么第一版测出 51ms):显式 CHECKPOINT 强制落盘会绕过内联。如果你想自己验,跑默认自动提交,别加 CHECKPOINT。转述别人基准前先跑一遍—— 同一段代码,实验设计差一步,结论差 6 倍(8.2 vs 51)。

三、DuckLake 的架构取舍:SQL catalog 赌的是什么

DuckLake 的核心赌注一句话:元数据操作的复杂度,应该交给数据库 40 年积累的 ACID 机制,而不是在文件系统上重新发明一遍。

换来什么:

  • 跨表原子事务——Iceberg/Delta 各表独立 commit,跨表一致性要应用层自己拼;DuckLake 一次 SQL 事务天然跨表。
  • 零 compaction 运维——没有 manifest 就没有小文件问题,「湖仓变慢的第一原因」直接不存在。
  • 迁移是可逆的——0.3 起 iceberg_to_ducklake() 只拷元数据不拷数据文件(快照历史保留),COPY FROM DATABASE 双向深拷最新快照。试错成本低。

付出什么:

  • 引擎广度——目前 DuckDB 系原生,Spark/Trino/DataFusion/Pandas 客户端年轻;5 个引擎要读同一张表的场景,Iceberg 不可替代。
  • catalog 成了一个基础设施——「元数据在 Postgres 里」意味着你要养一个 Postgres(小团队能接受,大平台有自己的 catalog 体系)。
  • 并发写模型——单 catalog 库的写并发上限取决于那个数据库;超大团队的高并发写平台场景,Iceberg 的 catalog 生态更成熟。

一条隐藏彩蛋 :DuckLake 官网部署列表里有「DuckDB + Quack (beta)」客户端—— 前篇 讲过 Quack 是 2.0 转正的网络协议,DuckLake 已经把它列为一等部署形态。DuckDB 帝国的三件套(内核 + 湖仓格式 + 网络协议)在这个列表里合流了。

四、选型决策树(对着抄)

你的表需要被几个引擎读写?├─ ≥3 个引擎(Spark+Trino+Flink…)→ Iceberg(广度不可替代)│    └─ 有 Databricks 平台 → Delta(UniForm 已打通互操作)├─ 只有 DuckDB/ 分析系引擎
│    ├─ 写入是高频小 append/ 频繁更新 → DuckLake(内联红利吃满)│    ├─ 大批量写入为主 → DuckLake 仍可(运维最简),或 Iceberg
│    └─ 需要跨表原子事务 → DuckLake(唯一原生支持)├─ upsert/CDC 密集 + 低延迟 → Hudi
└─ 全在阿里云 / 流式场景 → Paimon

给三类使用者的直接建议:

  • 个人 / 小团队(数据 pipeline ≤ 5 人维护):DuckLake + Postgres catalog,一次 ATTACH 就有湖仓,别搭 Iceberg 那套平台。
  • 中台团队(多引擎共享表):Iceberg 是安全答案;把 DuckLake 当「边缘 / 原型环境」的快速选项。
  • Databricks 用户:留在 Delta,UniForm 已经解决互操作焦虑。

五、风险与坑

  1. 格式年轻,锁版本——DuckLake 1.0(4/13)不到一年,2.0 spec(含 v1.1)在路上;生产锁 duckdb+ducklake 版本,升级前测。
  2. 「零 manifest」不等于「零运维」——catalog 数据库自己要备份 / 监控 / 容量规划;SQLite catalog 只适合单机实验,生产用 Postgres。
  3. 内联阈值是性能开关——默认 10 行;大批量写入场景它没意义,别拿「8.2ms」的基准套自己「每次写 100 万行」的负载。
  4. 引擎绑定是真实成本——选 DuckLake = 数据链路里锁定 DuckDB 系读取端;如果明年要接 Flink 实时消费,迁移路径存在(iceberg_to_ducklake 双向)但需要重排管道。
  5. 基准数字的边界——本机 8.2ms 是「SQLite catalog + 本地盘 + 200 次小 commit」的量级结论;不同 catalog(Postgres vs SQLite)、不同硬件、不同写入模式会显著不同。hikmah 的 Iceberg 9→202ms 是转述,未独立复测,引用时注明。

六、总结:3 个「最值得记住」的判断 + 1 句话

  1. DuckLake 用「元数据进 SQL」换来了高频小写入场景的代际优势——8.2ms 恒定、零文件、跨表事务、零 compaction,本机复测全部坐实;它不是「更好的 Iceberg」,是「不需要 Iceberg 的那类团队」的答案。
  2. 表格式选型的第一问不是「哪个最好」,是「几个引擎读你的表」——≥3 个引擎 Iceberg 不可替代;单引擎 + 讨厌运维,DuckLake 用一半的成本给你 80% 的能力,还带着可逆迁移。
  3. 基准复测必须自己做一遍——同一条基准,实验设计差一步(显式 CHECKPOINT),结论差 6 倍(8.2 vs 51ms)。转述数字前先跑一遍,是本系列的方法论沉淀。

一句话:战争结束了——Iceberg 拿下平台层,Delta 守住 Databricks,DuckLake 拿下了「下一个十亿张小表」:那些压根不会请平台团队的团队。


参考与延伸

by 飞熊 · yunying(增长运营官)· 实测环境 Ubuntu + Python 3.12 + duckdb 2.0.0 + ducklake 扩展(2026-10-30);stars 为 GitHub 页面实核;release 版本号经 shields.io 实核(Iceberg 1.12.0/Delta 4.4.1/Hudi 1.2.1/Paimon 2.1.0);Iceberg 对照数字未独立复测已标注「转述 + 机制推导」

正文完