轻量转换:默克用 DuckDB 把 Spark 作业提速十倍

摘要
Palantir 架构师 Chad Walquist 与默克(Merck KGaA,德国达姆施塔特)核心数据平台负责人 Nicolas 对谈,介绍轻量转换(Lightweight Transforms)如何改变数据处理方式。轻量转换让平台内运行不同类型的计算引擎:传统上 Palantir Foundry 默认用 Spark 或 Flink 作为运行时,现在可以换成 DuckDB、Polars、Data Fusion,甚至自带引擎。默克的体量惊人——平台每天约 10 万次构建,其中大部分代码是 PySpark 写的。Nicolas 观察行业基准后持续推动 Palantir 团队,促使轻量转换在近几个月被重新架构,而客户反馈正是重构的核心动力。
默克看到的收益「好得难以置信但真实存在」:跨作业普遍约 10 倍的性能提升,作业更快且消耗更少资源。关键架构解锁是把 S3 API(S3 代理)作为标准接口——所有框架对 S3 对象存储的支持最好,避免专有 API 成为瓶颈,从而可以接入任何引擎;DuckDB 因其稳定性与性能(高效的 S3 Parquet 读写器)成为默克的当前首选。
生产中已有大量真实案例:控制器域的数据供应链作业从 6-7 小时降到 20-26 分钟;约 1000 行复杂 PySpark 代码经开源库 SQLFrame 转译为 DuckDB SQL,从 1-3 小时降到 30-40 分钟且每天运行;长尾的 SAP 清洗作业在仅 2 核 15GB 内存下跑得比 16 核 Spark 更快。Nicolas 的更大愿景是 Iceberg 湖仓标准与「多模态数据平面」:任何存储、任何计算、任何位置,为正确的任务选择正确的引擎。
正文
一、100,000 次构建/天:默克的平台规模与轻量转换
Nicolas 自 2019 年加入默克,领导核心数据平台团队,Foundry 是其中之一(合作关系更早于他的入职)。他介绍,默克在平台上有大量管道——粗略估计每天约 10 万次构建(builds)。其中大部分代码用 PySpark 编写。如此规模下,如何让计算更高效,是他职责的核心问题。
轻量转换的概念其实已存在一段时间,但 Palantir 在近几个月重新引入并大规模重构了其后端——很大程度上来自 Nicolas 这样的客户反馈与迭代意愿。它允许平台内运行不同类型的计算引擎:传统上 Spark 或 Flink 是 Palantir 内的默认运行时,现在可以有它们,也可以有 DuckDB、Polars、Data Fusion 等不同引擎,甚至自带引擎。对默克而言,收益是清晰可见的运行时间缩短——转换作业更快,而且需要更少的资源,两者都直接转化为成本节省。
为什么快这么多?Nicolas 归因于新一代计算引擎对超大规模云实例硬件的利用:NVMe SSD、高内存实例。90%(对默克甚至接近 99%)的工作负载根本不需要分布式系统——不需要 Spark,也就没有分发任务、收集结果的开销;它在单台机器上运行,配以非常快的磁盘。即使数据超过实例内存(Parquet 文件解压进内存可能产生数百 GB 数据)也没问题——新引擎基于流式处理,在 CPU、内存与磁盘之间灵活调度。Chad 总结:基于 Rust 的高性能框架、单节点、更快的磁盘溢出(disk spillover)——这些因素叠加,真正改变了计算的范式。这正是 Nicolas 不断「追着 Palantir 团队」说「是时候了」的原因——今年早些时候,这个想法终于起飞。
二、S3 API 作为标准:解锁任意计算引擎
被问到「把既有 PySpark 管道迁移到轻量转换是什么感觉」时,Nicolas 先退一步,强调真正让新版轻量转换成为可能的根本改变:把 S3 API 作为标准接口(即 S3 代理)。因为每个框架获得的最佳支持都来自 S3 对象存储,让 S3 API 成为轻量转换的接口,就是解锁一切的「游戏规则改变者」——不再有专有 API,不再出现「今天我们支持这个,明天新 API 来了又要支持引擎 X、引擎 Y」的瓶颈。一旦轻量转换切换到 S3 API,就能利用任何引擎。
默克已经观察这个领域一段时间:就稳定性与性能而言,目前的领先者是 DuckDB——它有完美且高效的 S3 Parquet 读写器。当它与轻量转换容器结合时,实现快速构建几乎没有任何阻碍。Chad 指出,这一基础架构转变不仅解锁了 DuckDB,也让许多其他引擎获得更好的性能与互操作性——「现在人们也可以自带引擎」。
默克的作业呈典型的双峰分布:一端是运行数小时、消耗大量计算秒与成本的作业;另一端是长尾——数百个只跑几分钟、但运行非常频繁的作业。两者都需要解决方案。Nicolas 团队内部创建了一个可复用的库:基于开源框架 SQLFrame——它实现了兼容 PySpark 的 API,可以把现有 PySpark 代码转译(transpile)为 DuckDB 的 SQL,再接入 Foundry 的输入与输出。这个库一石二鸟:交给处理高影响数据集(运行数小时、平台上成本极高)的强力用户;同时嵌入高度标准化的流程——比如 SAP 数据集,每个数据集都需要对字符串列做同样的清洗步骤,而作为有历史的公司,默克有大量 SAP 系统,平台上有数千个这样的数据集。「做一次,然后全面推广」——这成了一个巨大的转换生成器。
三、生产中的成果:7 小时到 20 分钟
Nicolas 展示了两个已在生产中的真实例子。第一个是公司控制器(controlling)域的转换作业:整个控制器域的数据供应链被汇聚到一起。这个作业过去用至少 8 到 16 个执行器(executor),运行 6 到 7 小时;6 月或 7 月迁移后,只要 20 到 26 分钟(运气好时更快)。这还不是难作业:只是一些数据集的 union、加几个过滤。关键差异在于 DuckDB 能向量化大量指令,并且拥有 Spark 开源版不具备的高效 UNION ALL 能力。对平台所有者这是好事,对最终看报告、仪表盘、数据产品与 AI 输出的控制器或负责人同样如此——从数据摄入到成品数据产品的周期大幅缩短。Chad 算了一笔账:7-8 小时降到 20 分钟,单这一项就超过 10 倍——当然并非所有用例都如此,这个作业现在用单节点 4 到 8 核而不是 8 个节点,算是极端例子,但它确实说明了引擎级优化(比如单节点上的 union 远胜分布式系统中昂贵的汇集操作)叠加节点规模、Rust 基础等带来的效果。
第二个例子更有意思:约 1000 行复杂 PySpark 代码经 SQLFrame 转译为 DuckDB SQL——不是简单的 union,而是真正的复杂转换。运行时间从 1 到 3 小时降到 30-40 分钟以下,而且这个作业至少每天运行——影响被运行频次成倍放大。第三个例子是 SAP 的 MSEG 表(SAP 中较大的表之一)的清洗作业:属于长尾中「跑得很频繁」的那类。图表只显示最近 1000 次运行,可以清楚看到迁移点:Spark 运行时需要 15、16 分钟(运气好 6 分钟),而现在只用约 2 个 CPU 和 15GB 内存。Chad 感叹:通常「提速 = 加资源,减资源 = 变慢」,这里却用更少的资源换来更快的运行——「听起来好得难以置信」,但数据就在那里,它真的有效。
开源在这里扮演重要角色:SQLFrame 是开源库,你要知道自己签下了什么,但也因此可以贡献代码、提交问题描述与可复现问题,由社区修复或自己修复——DuckDB、Polars 同样如此。这正是开源之美。
四、更大的愿景:Iceberg 湖仓与多模态数据平面
被问及未来时,Nicolas 说最兴奋的是湖仓(lakehouse)方向:Iceberg 首次提供了一个所有厂商大致能同意的标准协议(虽然远非完美)。Foundry 已拥抱 Iceberg,他正与 Palantir 同事及其他厂商合作测试与采用。这让默克能为正确的任务选择正确的引擎——也许用 DuckDB,也许用某个云数仓,最终基于自身前提与技能组合决定什么工具能为业务提供最大价值。
Chad 指出,这正是「多模态数据平面」(multimodal data plane)的论点:任何存储、任何计算、任何位置。Nicolas 补充,虚拟表(virtual tables)出现后,默克已经在生产环境中写入与读取 BigQuery、Snowflake、AWS Iceberg、Glue catalog 等——两年前这完全不可能,即使有也需要大量 hack,而今天已被原生支持,真正让默克建立起一个深度整合的平台生态。真实的大型企业(尤其默克这样经历过并购与时间积累的公司)拥有极其复杂、异构的架构:完美世界里你会重新平台化一切、从干净的白板开始,但那永远不会发生——所以关键在于「拥抱混乱」,而工具正是为此而设。
他还希望与 Palantir 继续合作让 DuckDB 集成成为「一等公民」(很多其他客户也想要),并暗示平台仍有基础设施层面的极限可以突破——与裸机性能相比「这还能更快」——过去从没有人用 Spark 触到过那些边界,现在是时候推一推了。对默克而言,这种迁移不止是省钱:腾出的算力与容量,正是用来构建新东西、构建 AI 用例、利用 AIP 的空间——如果一直停留在 Spark 引擎上,这些几乎不可能。
觉得有用?分享给一个需要的朋友 🙏