Ingesting the Milky Way: Petabyte-Scale with Zerobus Ingest
TL;DR · AI 摘要
Zerobus Ingest 是 Databricks 推出的无服务器流式数据摄入服务,支持每秒 12GB 的吞吐量,无需手动管理基础设施。
核心要点
- Zerobus Ingest 支持每秒 12GB 的吞吐量,可处理 1PB 数据仅需 24 小时。
- Zerobus 采用动态分区机制,实现自动扩展,无需手动配置。
- Zerobus 直接写入 Delta 表,无需 Kafka 管道,简化数据摄入流程。
结构提纲
按章节快速跳转。
- §引言
Zerobus Ingest 是 Databricks 推出的无服务器流式数据摄入服务,旨在解决高吞吐量数据摄入问题。
Zerobus 采用动态分区机制,实现自动扩展,无需手动配置。
Zerobus 自研零拷贝 Protobuf 解码器,提升数据处理效率。
Zerobus 实现延迟优化的写前日志,确保数据写入湖仓的稳定性。
Zerobus 在 24 小时内处理了 1PB 数据,吞吐量达到每秒 12GB。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- Zerobus Ingest 架构
- 动态分区机制
- 自动扩展
- 无需手动配置
- 零拷贝 Protobuf 解码器
- 提升数据处理效率
- 延迟优化的写前日志
- 确保数据写入湖仓的稳定性
金句 / Highlights
值得收藏与分享的关键句。
Zerobus Ingest 支持每秒 12GB 的吞吐量,可处理 1PB 数据仅需 24 小时。
Zerobus 采用动态分区机制,实现自动扩展,无需手动配置。
Zerobus 直接写入 Delta 表,无需 Kafka 管道,简化数据摄入流程。
吞入银河:使用 Zerobus Ingest 实现 PB 级规模 | Databricks 博客
跳转到主要内容
数据工程
2026 年 6 月 11 日
吞入银河:使用 Zerobus Ingest 实现 PB 级规模
深入探讨实现每张表 12 GB/s 的架构,以及无限可能
作者:Aleksandar Tomić、Victoria Bukta、Nikola Obradović、Danilo Najkov、Branko Grbić 和 Milos Milovanovic
摘要
- Databricks Zerobus Ingest 是一种无服务器流式 API,使团队能够即时部署 PB 级规模的数据管道,而无需手动管理基础设施。
- Zerobus 的架构依赖于动态分区,以自动扩展计算资源,高效处理不可预测的数据量,无需复杂的调优。
- 这种零配置框架可以轻松处理大规模工作负载,在 24 小时基准测试中展示了将超过 12 GB/s 的吞吐量写入单个表的能力。
遥测数据无处不在。工厂车间上的物联网传感器。扫描大气层的卫星阵列。自动驾驶车辆每秒记录数千个事件。这些系统都面临相同的底层问题:需要将连续的、高流量的时间序列观测数据写入某个可查询的位置。它需要快速、可靠,而且不需要工程团队花费数周时间对基础设施进行调优和维护,这在基于 Kafka 的工作负载中是常见的。
这就是 Zerobus Ingest 所要解决的问题。Zerobus 是 Databricks 提供的完全托管、无服务器的流式数据摄入服务。它是一种基于推送的 API,可以从任何生产者接受数据,并直接写入由 Unity Catalog 管理的 Delta 表中。
- 无需提供基础设施。
- 无需维护连接器管道。
- 无需分区或经纪人决策。
相反,你只需创建一个表并推送数据。数据会立即进入你的湖仓,几秒钟后即可查询。当你目标是湖仓时,你不再需要运行 Kafka 作为管道。
我们使用了 NASA 的 NEOWISE 数据集,该数据集代表了 11 年内 2000 亿个数据点,用于对 Zerobus Ingest 进行基准测试,在不到 24 小时内摄入了 1 PB 的数据,且无需任何预配置,延迟稳定。
通过在 24 小时内摄入 1 PB 的数据,我们展示了 Zerobus 保持每张表连续 12 GB/s 吞吐量的能力!🚀
现在实现 PB 级规模:流式传输银河(12GB/秒/表)
展开
上述可视化图表重放了一年的数据。随着这些检测数据写入表中,银河的圆盘以橙色逐渐显现;青色的新月标记了望远镜在任何给定时刻指向的天空区域。
有关如何自行运行基准测试的更多信息,请阅读 Databricks 社区上的这篇配套博客。
本文将介绍我们实现这一目标的三个设计决策。
- 设计一个通过动态分区实现自动扩展的系统。
- 构建我们自己的零复制 Protobuf 解码器。
- 在数据发布到湖仓之前,实现一个优化延迟的预写日志。
通过回到第一性原理,我们设计并构建了一个系统,能够“神奇地”处理数据生产者产生的PB级规模的工作负载。
通过动态分区实现自动扩展
我们试图解决的问题是如何实现高效的自动扩展,以达到弹性“限制”扩展。
我们的假设是,通过摆脱静态分区,转向流/连接的逻辑单元,我们可以在保持排序保证的同时,实现真正的自动扩展和重新平衡,而排序保证对于消费工作负载非常重要。
#### 静态分区的问题
在消息总线架构中,分区既是并行的单位,也是排序的单位。这种耦合关系一旦有消费者依赖它,就会带来痛苦的限制。
排序通常是按分区的保证,而不是按生产者的。分区的数量和数据在其中的分布会影响消费者跟上摄入数据的能力。这意味着:
- 如果分区数量发生变化,将生产者的消息映射到分区的路由函数现在可能会将它们发送到不同的分区。消费者现在必须处理这种变化。
- 实际上,大多数团队将分区拓扑视为不可变的。你为峰值负载进行配置,并永远保留这种基础设施。你可以添加分区,但通常不能安全地减少它们。
- 标准的解决方法是从消息中的一个字段派生出一个分区路由键。这有助于排序一致性,但仍然无法解决缩放问题。
#### 我们将排序保证转移到流连接
在传统系统中,排序是分区级别的保证。在Zerobus Ingest中,排序是流连接级别的保证。
当生产者通过Zerobus打开一个流(连接到我们的服务器)时,他们正在向服务注册一个逻辑身份。在该连接的生命周期内,无论哪个“分区”Pod处理它们的数据,它们的数据都会按顺序到达。
“你的流是有序的”,而不是“你的分区是有序的”。这就是合同。
#### 热路由和真正的自动扩展
在内部,Zerobus Ingest将流分布在一组Pod池中。路由是基于启发式的:如果某个Pod运行过热,新的流入流会被路由到另一个Pod。生产者对此毫不知情。他们的排序保证不受影响。
排序存在于流级别,这意味着当需求激增时可以添加Pod,当需求下降时可以移除Pod。现有流会优雅地排水,新流将不再路由到那里。池随后缩小,保持计算利用率高效。
这就是真正的自动扩展。粒度单位是流连接,而不是分区分配。
我们的动态分区设计使Zerobus能够自动扩展到单个表每秒超过12GB的吞吐量,同时保持成本效率。
零拷贝高性能数据处理
Zerobus的主要目标是允许高效地逐行传输任意规模的数据流。为了实现这一点,我们需要完全避免任何不必要的复制和内存分配——从客户端发送到Zerobus的输入格式,到保证持久性和开放Delta格式的内部格式。
Zerobus目前支持以下消息格式。
| Zerobus 格式 | 使用场景 | |--------------|----------| | protobuf | 通用,快速逐条摄入。 | | arrow | 快速批量摄入。 | | json | 批量或逐行;方便,但比protobuf和Arrow慢。 |
在我们进行的众多优化中,我们将通过 ZeroParser —— 我们的自定义 protobuf 解码器,来说明零拷贝方法。
标准的 protobuf 解码器迫使你在速度和灵活性之间做出选择。通常,protobuf 解码器依赖于编译时代码生成(codegen)或运行时反射。
- 代码生成速度快,但需要在编译时获取描述符。Zerobus 在运行时从任意用户模式中动态接收描述符。代码生成不是一个选项。
- 运行时反射解决了灵活性问题,但带来了性能上的问题。动态的 protobuf 解码器速度很慢,并且需要在运行时构建内存中的对象图,导致大量的小内存分配。
这两种方法都不令人满意。我们需要在动态描述符支持的同时,保持代码生成的性能特征。
结果是我们构建了 zeroparser:通过单次解析和零内存分配来弥合这一差距,即使在动态描述符和复杂模式下,也能实现每个 CPU 核心约 1 GB/s 的 protobuf 解析吞吐量。
Zeroparser 允许直接解析线上的格式,而无需对传入的对象进行解构,从而避免了内存复制和分配。通过这种方法,Zerobus 可以在保持动态提供 protobuf 描述符的完整灵活性的同时,实现比现有代码生成的 protobuf 解析方案更好的性能。
Rust 的生命周期系统在 Zeroparser 的设计中至关重要:它在协议解析期间保证编译时的安全性,同时保持原始线上的字节在网络中的独占所有权,消除了不必要的数据复制。
结果表明,尽管 Zeroparser 属于动态组,但它优于两个行业标准的基于代码生成的实现。
Zeroparser 作为 Zerobus SDK 的一部分在此处开源。
预写日志(Write Ahead Log)
流处理不仅仅是能够处理高吞吐量的工作负载。要成为一个真正的流服务,你还需要尽可能快速地支持消息传递。这种低延迟的数据传递正是流处理工作负载与批处理工作负载之间真正的区别。
为了支持这种低延迟的数据传递并保证持久性,Zerobus 实现了一个延迟优化的预写日志(WAL)。一旦消息持久化,Zerobus 会向客户端发送确认信息。而不是对每条记录单独确认,服务器会返回流中最高的已提交偏移量。其结果是这个异步确认循环。Delta Kernel Rust 用于写入 Delta 的核心逻辑。
这种异步设计对缓冲飞行数据的客户端至关重要。Zerobus 使用 gRPC 双向流,每个 Zerobus 流有两条通信线路:
- 一条用于发送消息
- 另一条用于接收偏移量确认。
一旦客户端接收到该偏移量,它可以安全地从本地飞行缓冲区中清除所有数据到该点之前的内容。所有这些都由 Zerobus SDK 处理。
WAL 使得客户端保持轻量。推送你的数据,接收确认,释放你的缓冲区。这种低延迟、高持久性的数据传递一直是团队选择 Kafka 的原因。Zerobus 给你同样的保证。
证明:摄取银河系数据
对系统进行基准测试的关键在于理解它在生产环境中的使用方式,然后模拟这种行为和使用方式。这就是为什么为了对 Zerobus Ingest 进行压力测试,我们决定选择 NASA 的 NEOWISE 数据集,并使用 Locust 来模拟现实世界中的数据汇聚模式。
为什么选择 Locust?数据汇聚问题
Zerobus Ingest 的设计目标是将来自许多独立生产者的流汇聚到一个目标表中。其吞吐量会随着并发打开的流数量而扩展。这意味着你无法通过单台机器或小型集群公平地对其进行压力测试。单个强大的主机在对我们的服务施加有意义的压力之前,就会耗尽自己的带宽或 CPU,因此实际上是在对生产者进行基准测试,而不是对 Zerobus。
为了模拟现实世界中的数据汇聚模式,我们使用 Locust 来协调通过多个 Pod 打开独立流,从而在大规模下对数据摄入进行压力测试。
Zerobus 的自动扩展功能会根据流的数量和吞吐量来处理数据摄入的速率。
测试配置
我们的基准测试部署在 Kubernetes 上,包含一个 Locust 主节点和一个 Locust 工作节点舰队,每个工作节点作为一个独立的 Pod 运行。关键参数如下:
| 参数 | 值 | |------|----| | Locust 工作节点 | 2,048 | | 每个工作节点的 Zerobus 流 | 1 | | 总并发 Zerobus 流 | | | 启动速率 | 0.5 用户/秒 | | 测试时长 | 约 25 小时(含 1 小时工作节点启动时间) | | 消息格式 | Protocol Buffer 2(proto2)二进制 | | 每个流的在途记录数 | 50,000(最大) | | 工作节点 CPU / 内存 | 每个 Pod 1.5 核心 / 2 GiB | | 工作节点临时存储 | 10 GiB(本地 Parquet 缓存) |
每个工作节点都会获得一组唯一的 Parquet 文件列表进行摄入。工作节点会流式传输其对应的切片,且不会重复行。
测试结果
我们的测试结果表明,Zerobus Ingest 能够在 24 小时内,从 2,048 个并发工作节点向单个表持续写入 12 GB/s 的数据。在此期间,Zerobus 摄入了超过一万亿条记录。
对 client_ts_ms 列按 5 秒时间桶进行聚合,可以得到精确的、由服务器确认的已提交行数和接收字节数的视图:
$$ /$ $$
此查询针对的是实时的 Unity Catalog 表。这些数字反映的是已完全提交到 Delta 存储的行数。
性能结果
| 指标 | 可持续吞吐量(行/秒) | 可持续吞吐量(MB/秒,proto2 线) | 总摄入行数 | |------|------------------------|----------------------------------|------------| | 12,000,000 | 11.8GB/s | 1.04万亿 | 24小时 |
想要自己运行测试吗?
完整的基准测试框架,包含数据集准备、生产者代码以及针对你自己的 Zerobus 端点运行的说明。点击此处查看。
下一步
Zerobus Ingest 现在已在 Databricks 上正式发布,已准备好处理所有你的生产工作负载。
我们对 Zerobus Ingest 的性能指标是每表 12GB/s,这是开箱即用的性能。如需提高配额,请联系你的账户团队。
路线图包括:
- Kafka 生产者 API 支持
- MQTT API 支持
- 救援列
- 系统元数据列
- Avro 支持
告诉我们你希望我们下一步如何发展 Zerobus!你认为流处理的下一个前沿是什么?在我们的配套 Databricks 社区博客上留言告诉我们。
如果你准备开始使用 Zerobus Ingest,请参考我们的技术文档、Zerobus Ingest SDK 或查看包含 Neowise 基准测试的 GitHub 仓库。
获取最新文章
订阅我们的博客,获取最新文章直接发送到你的邮箱。
注册
查看所有博客
slice-start id="_gatsby-scripts-1"
slice-end id="_gatsby-scripts-1"