凌晨两点,你的实时看板突然报警。一条用户行为数据需要紧急补录——就一行。但在现有的数据湖架构里,这意味着新建一个Parquet文件、重写元数据、更新目录服务。等这套流程跑完,天都快亮了。

这不是段子。这是DuckDB Labs团队在过去几年反复听到的抱怨。他们本周发布的DuckLake 1.0,正是冲着这个"小修改、大动静"的顽疾来的。

打开网易新闻 查看精彩图片

从宣言到产品:一场酝酿一年的架构实验

2024年5月,DuckDB Labs扔出一份技术宣言,核心主张相当激进:用关系型数据库(RDBMS)来管数据湖元数据。不是当辅助工具,而是作为核心架构组件。

当时业内反应两极。支持者觉得思路清奇——PostgreSQL、SQLite、DuckDB这些成熟数据库,处理事务性更新本就是看家本领。质疑者则皱眉:数据湖架构好不容易统一到Iceberg、Delta Lake这些开放表格式,现在又要引入数据库层,会不会把简单问题复杂化?

一年后,DuckLake 1.0给出答卷。这不是概念验证,是生产就绪的规范发布。团队选择用"事件还原"的方式讲清楚:他们到底解决了什么问题,以及为什么偏偏是RDBMS能解。

Parquet的甜蜜点与死穴

要理解DuckLake的设计,得先看清现有架构的瓶颈在哪。

当前主流数据湖方案——Databricks、Snowflake、Google BigLake等底层都依赖Parquet列式存储。这种格式在批量分析场景表现优异:高压缩比、向量化读取、与计算引擎配合默契。但它的设计哲学是"一次写入、多次读取",天生不擅长增量更新。

Hannes Mühleisen,DuckDB Labs联合创始人兼CEO,同时也是阿姆斯特丹数学与理论计算研究中心的教授,向The Register解释了这里的矛盾:「你修改表中一行数据,由于架构设计方式,必须写一个包含这行数据的新文件,再写一堆元数据,然后让目录服务更新。这非常低效,因为Parquet格式本身就不适合存单行数据——它想存的是百万行规模。而且从对象存储里反复捞这些小文件,传输开销极高。」

这不是某个厂商的实现缺陷,是开放表格式与底层存储格式的结构性错配。Iceberg和Delta Lake用元数据层抽象解决了"表"的语义问题,但没解决"行"的物理存储问题。

结果就是:流式摄入、实时修正、CDC(变更数据捕获)这些场景,在数据湖架构里始终磕磕绊绊。要么忍受延迟批量刷写,要么接受小文件爆炸带来的查询性能雪崩。

DuckLake的解法:把数据库当作"缓冲带"

DuckLake的核心设计差异可以用Mühleisen的一句话概括:「我们有一个数据库,而且我们不害怕使用它。」

具体实现分三层:

第一层是元数据目录。DuckLake把表结构、文件清单、版本历史、变更日志全部放进RDBMS管理。可以是PostgreSQL、SQLite,也可以是DuckDB本身。这层不碰实际数据,只负责" bookkeeping "——记录什么文件存了什么数据、数据之间什么关系、时间线上发生了什么。

第二层是变更缓冲。当用户插入、删除或更新单行数据时,DuckLake不急着写Parquet,而是先把变更写进RDBMS的表中。这里利用了数据库的OLTP能力:行级锁、事务ACID、高效索引。单行操作毫秒级完成,对用户完全透明。

第三层是批量刷写。RDBMS后台持续监控变更累积量,当达到配置阈值(比如10万行或5分钟),自动将缓冲的变更合并、排序、压缩,生成新的Parquet文件写入对象存储。旧文件标记失效,元数据原子性切换。

Mühleisen强调这个过程的透明性:「元数据库存储增删改等小规模变更,直到最终'刷写'回Parquet成为相对较大的文件,同时对用户完全不可见。」

换句话说,用户看到的始终是一张逻辑表,无论背后数据是躺在RDBMS缓冲层还是Parquet文件里。查询引擎通过统一元数据层路由,小变更走RDBMS索引快速响应,历史大数据走Parquet批量扫描。

为什么是RDBMS,而不是专用缓存?

这里有个关键选择:DuckLake本可以用Redis、Kafka或其他流式中间件做缓冲层,为什么偏偏选RDBMS?

答案藏在数据湖的"元数据爆炸"问题里。

现代数据湖的元数据规模已经逼近甚至超过原始数据。Iceberg的manifest清单、Delta Lake的transaction log、分区统计、列级统计、文件级min/max索引——这些元数据本身就需要一个可靠的存储系统。与其为缓冲层再引入新组件,不如让元数据库"一岗双责":既管目录,又管变更缓冲。

这个设计降低了架构复杂度。运维团队不需要维护额外的缓存集群,开发者不需要学习新的API。SQL接口统一暴露,事务语义保持一致。对于已经使用PostgreSQL或DuckDB作为catalog的团队,迁移成本几乎为零。

更深一层,RDBMS的成熟生态成了DuckLake的杠杆。备份恢复、权限控制、监控告警、连接池管理——这些基础设施直接复用,不需要重新发明轮子。

生产就绪意味着什么

DuckLake 1.0的发布标签是"production-ready",这不是营销话术。团队在过去一年与早期用户打磨了边界场景:RDBMS缓冲层满溢时的降级策略、跨可用区的元数据同步、与现有Iceberg/Delta Lake表的互操作。

一个值得注意的细节是格式兼容性。DuckLake没有另起炉灶定义新的表格式,而是基于开放的Iceberg和Delta Lake规范扩展。这意味着DuckLake管理的表,可以被Spark、Trino、Flink等引擎直接读取——只要它们支持标准开放表格式。缓冲层的小变更在查询时实时合并,对下游引擎无感知。

这种"增量创新"而非"颠覆替换"的策略,降低了企业采纳门槛。不需要推翻现有数据湖架构,只需在元数据层引入RDBMS缓冲,渐进式解决小文件问题。

行业坐标:数据库与数据湖的边界重构

DuckLake的发布,放在更大的技术演进脉络里看,是一系列"数据库化"趋势的最新节点。

过去五年,数据湖仓(lakehouse)架构的核心叙事是"用开放格式打破数据仓库的封闭性"。Iceberg、Delta Lake、Hudi让数据湖具备了事务性和版本管理能力,模糊了湖与仓的边界。但这个进程始终有一个假设:元数据层是轻量的、状态less的,真正的重量放在对象存储。

DuckLake挑战了这个假设。它证明元数据层本身可以成为架构杠杆——用RDBMS的OLTP能力补强Parquet的OLAP优势,让"湖"在实时性维度上真正逼近"仓"的体验。

这不是回到传统数据仓库的老路。数据湖的核心优势——开放格式、存储计算分离、云原生弹性——全部保留。DuckLake只是在关键路径上引入了一个经过验证的抽象层,用数据库的工程成熟度解决特定场景的性能瓶颈。

值得关注的是DuckDB自身的定位演变。这个诞生于学术项目的嵌入式分析数据库,最初以"单机极速查询"闻名。现在通过DuckLake,它正在向数据基础设施的更深一层渗透——不是取代Spark或Snowflake,而是在它们力所不及的缝隙里建立新据点。

谁该关注这个发布

三类团队值得评估DuckLake的适用性:

实时数据管道建设者。如果你的Flink或Spark Streaming作业因为小文件问题被迫加大批处理窗口,DuckLake的缓冲机制可能直接消除这个权衡。

CDC场景重度用户。从业务数据库同步变更到数据湖,传统方案需要复杂的合并逻辑。DuckLake让变更先入库再批量刷写,简化了链路,降低了延迟。

成本敏感的中型团队。不需要采购专门的实时数仓产品,用开源RDBMS+DuckLake组合,可能以更低成本获得近实时能力。

当然,新架构总有代价。RDBMS缓冲层引入了额外的运维面,需要监控容量和性能。跨地域部署时,元数据同步的延迟需要评估。这些不是致命障碍,但需要在POC阶段验证。

数据收束

DuckLake 1.0的发布,用一组清晰的技术选择回应了数据湖架构的长期痛点:将RDBMS从"元数据附属品"提升为"变更处理核心",用数据库的事务能力弥补Parquet的增量更新缺陷。这不是对现有湖仓架构的否定,而是在开放格式基础上做的工程补强。

根据DuckDB Labs的发布节奏,从2024年5月的技术宣言到2025年5月的生产就绪版本,整整12个月的打磨周期。Mühleisen团队没有追逐"实时数据湖"的营销概念,而是聚焦于一个可量化的技术指标:单行变更的端到端处理成本。当这个成本从"新建Parquet文件+重写元数据"降级为"RDBMS行插入",实时场景的工程可行性发生了质变。

对于在数据湖实时化道路上反复试探的技术团队,DuckLake提供了一个值得验证的选项:不抛弃现有投资,不引入专有锁定,用数据库的成熟能力填补架构缝隙。这个思路本身,可能比具体实现更有长期价值。