DuckLake首席开发者:把元数据当关系数据库问题,湖仓查询就只剩目录和Parquet文件
DuckLabs首席开发者Pedro Holanda解释DuckLake 1.1的核心设计选择:用标准SQL数据库存储表元数据,取代散落在对象存储中的清单文件。查询路径变成:发出查询,服务器告诉你该读哪些Parquet文件,数据文件不变,只有目录在变。
传统湖仓格式把元数据拆成大量清单文件散布在对象存储里。每次查询,引擎都要遍历这些文件才能知道该读哪些Parquet数据文件。DuckLabs首席开发者Pedro Holanda认为这本质上是一个关系数据库问题,不需要用文件系统的方式解决。
他的解释很直接:你发出查询,服务器回答你该读哪些Parquet文件。Parquet文件本身不变,变的只是目录。这就是DuckLake把表元数据存进标准SQL数据库而非散布清单文件的原因。用户已经熟悉SQL和模式,不需要额外学习一套元数据遍历逻辑。
DuckLake 1.1在十月与DuckDB 2.0.0 LTS一同发布,带来了文件合并以及针对流式数据湖的内联与刷新机制。文件合并方面,当文件数量过多时,DuckLake可以把多个文件粘合成一个,减少请求数;这个操作可以跨多个快照执行,进一步压缩文件总量。内联方面,把实际数据表示直接作为表存储在目录中。Holanda说,构建DuckLake时他们意识到既然已经有了数据库系统和目录,为什么不把数据本身也放进表里?
这解决了流式场景中的小文件问题。多个数据源同时写入时,传统湖仓会产生大量碎片文件,查询时既要遍历元数据又要读取大量小Parquet文件,两头都慢。DuckLake通过内联和刷新把碎片吸收进目录,把合并操作推迟到需要时再执行。
LanceDB工程师Weston Pace在另一篇技术博客中从并发写入的角度补充了DuckLake的设计取舍。他把表格式的协调机制分为两类:零基础设施原子操作(依赖云存储的put-if-not-exists语义,无需额外服务但受限于约每秒十次提交)和集中式协调(DuckLake用Postgres实例作为提交协调器,通过互斥锁或CAS原语同步写入者)。集中式方案可能获得更高事务率,且适用于不支持原子创建的文件系统,代价是需要维护一个长期运行的服务。
DuckDB和DuckLake均以MIT许可证开源,由独立的DuckDB基金会监督。DuckLake不需要大规模服务器集群就能运行,部分原因是Parquet和DuckDB存储格式天然相似——都是列式组织、按行组划分,数据搬运步骤极少。