在 Rust 和 Python 项目中无需 JVM 和 PySpark 即可使用 Delta Lake
任何尝试在小服务或脚本中采用 Delta Lake 格式的人都会很快遇到一个残酷的现实。要读取几 GB 的事务日志文件,你必须拖上 Apache Spark,以及随之而来的重型 JVM 基础设施。在大型数据平台中这是合理的,但对于本地应用、后台微服务或 AWS Lambda 无服务器函数来说,这种解决方案显得过于繁琐。
Delta Lake 社区的开发者决定填补这一空白。他们创建了 delta-rs 项目——一个用于在 Rust 中处理 Delta Lake 的原生库,并提供官方的 Python 绑定。
为什么还需要另一个数据库
Delta Lake 格式非常出色,因为它解决了开放文件存储的主要痛点。它在 Parquet 文件之上添加了 ACID 事务日志、带回滚到先前版本能力的变化历史(时间旅行),以及严格的模式强制执行。
围绕 Delta Lake 的经典技术栈历来与 Scala 和 Java 绑定。如果你的主要技术栈是 Rust 或没有 PySpark 等重型框架的轻量级 Python,在 delta-rs 出现之前,你的选择非常有限。
该库为 Rust 提供了底层 API,为 Python 提供了高级接口。现在你可以用几行代码将带有 ACID 保证的数据写入 S3 存储桶或本地磁盘,而无需启动 JVM 进程。
Python 和 Rust 快速入门
Python 包接口 deltalake 设计得让开发者无需重新学习任何东西。它可以轻松集成熟悉的分析库——Pandas、Arrow 或 Polars。
在 Python 中写入和读取表的代码看起来非常熟悉:
import pandas as pd
from deltalake import DeltaTable, write_deltalake
# Создаем тестовый датафрейм и сохраняем его в формате Delta
df = pd.DataFrame({"id": [1, 2], "value": ["foo", "boo"]})
write_deltalake("./data/delta", df)
# Считываем данные обратно
dt = DeltaTable("./data/delta")
df_read = dt.to_pandas()
assert df.equals(df_read)
一个有趣的细节:你可以立即从 Rust 应用中打开同一个表。无需手动组装元数据。该库会自动解析 _delta_log 目录中的 JSON 提交日志。
在 Rust 中读取表元数据的示例:
use deltalake::{open_table, DeltaTableError};
use url::Url;
#[tokio::main]
async fn main() -> Result<(), DeltaTableError> {
let delta_path = Url::from_directory_path("/abs/data/delta").unwrap();
let table = open_table(delta_path).await?;
let files: Vec<_> = table.get_file_uris()?.collect();
println!("{files:?}");
Ok(())
}
底层原理和集成
高性能和低内存消耗并非偶然。该项目构建在 Apache Arrow 引擎和 DataFusion 向量化引擎之上。Rust 用于安全内存管理以及处理云存储时的并行 I/O。
该库可以直接与 AWS S3、Google Cloud Storage、Azure Blob Storage 以及本地文件系统配合使用。
由于共享 Rust 和 Arrow 的基础,delta-rs 迅速成为现代数据处理生态系统的一部分。流行工具开箱即用地支持它:
- Polars 使用 delta-rs 直接读写 Delta 表。
- DuckDB 可以对 Delta 日志执行分析型 SQL 查询。
- Da、Dask 和 Ray 在 Python 中使用此模块进行分布式数据处理。
- AWS SDK for Pandas 将其用作 Delta 格式的原生引擎。
实际用例
在哪些情况下 delta-rs 优于经典方法?
第一种情况是微服务架构。例如,你有一个 Rust 或 Python 服务,从消息队列收集事件,需要每五分钟向数据存储追加一批数据。为此启动 Spark 集群既昂贵又难以维护。使用 delta-rs,服务只需链接该库并直接写入 S3。
第二种情况是轻量级 ETL 管道。如果你的数据量以几十或几百 GB 计,Polars 配合 delta-rs 在单台实例上的处理速度比 PySpark 集群的预配还要快。
第三种情况是无服务器架构。在对镜像大小和启动时间有严格限制的 AWS Lambda 函数中,适配 Java 环境是个问题。包含 delta-rs 的编译后 Rust 二进制文件可以在几毫秒内启动。
该项目有局限性吗?是的,Delta Lake 规范相当广泛,并且 Databricks 还在不断更新它。一些稀有或新格式功能在 delta-rs 中的实现会有轻微延迟。在使用带有特定条件的 MERGE 等复杂操作之前,你应该查看项目文档中的支持功能表。
结论
delta-io 团队做得非常出色。这个原生 Rust 库让 Delta Lake 格式的工作重新变得轻量。
如果你需要事务性、数据版本控制和基于 Parquet 的可靠存储,但不想处理 Java 基础设施,一定要试试 delta-rs。你可以用命令 pip install deltalake 在 Python 中安装该包,并通过 cargo add deltalake 将其添加到 Rust 项目中。
相关项目