Delta Lake ohne JVM und PySpark in Rust- und Python-Projekten
Jeder, der versucht hat, das Delta-Lake-Format in kleinen Diensten oder Skripten zu verwenden, stößt schnell auf eine unangenehme Tatsache. Um nur ein paar Gigabyte Transaktionsprotokolldateien zu lesen, muss man Apache Spark mitschleppen, und damit die schwergewichtige JVM-Infrastruktur. In großen Datenplattformen ist das gerechtfertigt, aber für eine lokale Anwendung, einen Hintergrund-Microservice oder eine AWS-Lambda-Serverless-Funktion fühlt sich eine solche Lösung viel zu umständlich an.
Entwickler aus der Delta-Lake-Community haben beschlossen, diese Lücke zu schließen. Sie haben das Projekt delta-rs erstellt – eine native Bibliothek für die Arbeit mit Delta Lake in Rust, mit offiziellen Bindings für Python.
Warum noch eine Datenbibliothek
Das Delta-Lake-Format ist großartig, weil es die Hauptprobleme offener Dateispeicher löst. Es fügt ein ACID-Transaktionsprotokoll über Parquet-Dateien hinzu, eine Änderungshistorie mit der Möglichkeit, auf frühere Versionen zurückzusetzen (Time Travel), und eine strenge Schema-Durchsetzung.
Der klassische Stack rund um Delta Lake war historisch an Scala und Java gebunden. Wenn Ihr primärer Stack Rust oder leichtgewichtiges Python ohne schwere Frameworks wie PySpark ist, waren Ihre Optionen vor delta-rs begrenzt.
Die Bibliothek bietet Low-Level-APIs für Rust und eine High-Level-Schnittstelle für Python. Jetzt können Sie Daten mit ACID-Garantien in einen S3-Bucket oder auf die lokale Festplatte in nur ein paar Zeilen Code schreiben, ohne JVM-Prozesse zu starten.
Schnellstart in Python und Rust
Die Python-Paket-Schnittstelle deltalake ist so konzipiert, dass Entwickler nichts Neues lernen müssen. Sie integriert sich einfach mit vertrauten Analyse-Bibliotheken – Pandas, Arrow oder Polars.
Schreiben und Lesen einer Tabelle in Python sieht sehr vertraut aus:
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)
Ein interessantes Detail: Sie können dieselbe Tabelle sofort aus einer Rust-Anwendung öffnen. Keine manuelle Metadaten-Zusammenstellung ist erforderlich. Die Bibliothek parst automatisch das JSON-Commit-Protokoll im _delta_log-Verzeichnis.
Beispiel für das Lesen von Tabellenmetadaten in 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(())
}
Unter der Haube und Integrationen
Hohe Geschwindigkeit und niedriger Speicherverbrauch sind kein Zufall. Das Projekt basiert auf der Apache-Arrow-Engine und der DataFusion-Vektor-Engine. Rust wird für sicheres Speichermanagement und parallele Ein-/Ausgabe bei der Arbeit mit Cloud-Speicher verwendet.
Die Bibliothek kann direkt mit AWS S3, Google Cloud Storage, Azure Blob Storage und dem lokalen Dateisystem arbeiten.
Dank der gemeinsamen Grundlage auf Rust und Arrow ist delta-rs schnell Teil des modernen Datenverarbeitungs-Ökosystems geworden. Beliebte Tools arbeiten out-of-the-box damit:
- Polars verwendet delta-rs für direktes Lesen und Schreiben von Delta-Tabellen.
- DuckDB kann analytische SQL-Abfragen auf Delta-Protokollen ausführen.
- Da, Dask und Ray verwenden dieses Modul für verteilte Datenverarbeitung in Python.
- AWS SDK für Pandas verwendet es als native Engine für das Delta-Format.
Praktische Anwendungsfälle
In welchen Situationen schneidet delta-rs besser ab als der klassische Ansatz?
Der erste Fall ist Microservice-Architektur. Zum Beispiel haben Sie einen Rust- oder Python-Dienst, der Events aus einer Message-Queue sammelt und alle fünf Minuten Batches an einen Datenspeicher anfügen muss. Einen Spark-Cluster dafür zu starten ist teuer und komplex zu warten. Mit delta-rs verlinkt der Dienst einfach die Bibliothek und schreibt Daten direkt in S3.
Der zweite Fall sind leichtgewichtige ETL-Pipelines. Wenn Ihre Datenmengen in Zehn- oder Hunderten von Gigabyte gemessen werden, verarbeitet Polars in Kombination mit delta-rs diese auf einer einzelnen Instanz schneller, als ein PySpark-Cluster bereitgestellt werden kann.
Der dritte Fall ist Serverless-Architektur. In AWS-Lambda-Funktionen mit strengen Limits für Image-Größe und Startzeit ist es problematisch, eine Java-Umgebung unterzubringen. Ein kompiliertes Rust-Binary mit delta-rs startet in Millisekunden.
Hat das Projekt Einschränkungen? Ja, die Delta-Lake-Spezifikation ist ziemlich umfangreich und wird von Databricks ständig aktualisiert. Einige seltene oder neue Format-Features werden in delta-rs mit einer leichten Verzögerung implementiert. Bevor Sie komplexe Operationen wie MERGE mit bestimmten Bedingungen verwenden, sollten Sie die Tabelle der unterstützten Features in der Projektdokumentation prüfen.
Fazit
Das delta-io-Team hat hervorragende Arbeit geleistet. Die native Rust-Bibliothek hat die Leichtigkeit zurück in die Arbeit mit dem Delta-Lake-Format gebracht.
Wenn Sie Transaktionalität, Datenversionierung und zuverlässige Speicherung auf Basis von Parquet benötigen, aber sich nicht mit Java-Infrastruktur auseinandersetzen wollen, probieren Sie delta-rs auf jeden Fall aus. Sie können das Paket in Python mit dem Befehl pip install deltalake installieren und es einem Rust-Projekt über cargo add deltalake hinzufügen.
Ähnliche Projekte