Delta Lake senza JVM e PySpark nei progetti Rust e Python
Chiunque abbia cercato di adottare il formato Delta Lake in piccoli servizi o script si scontra rapidamente con una dura realtà. Per leggere semplicemente un paio di gigabyte di file di log delle transazioni, bisogna trascinarsi dietro Apache Spark e, con esso, l'infrastruttura JVM pesante. nelle grandi piattaforme dati questo è giustificato, ma per un'applicazione locale, un microservizio in background o una funzione serverless AWS Lambda, una tale soluzione risulta decisamente troppo ingombrante.
Gli sviluppatori della community di Delta Lake hanno deciso di colmare questa lacuna. Hanno creato il progetto delta-rs — una libreria nativa per lavorare con Delta Lake in Rust, completa di binding ufficiali per Python.
Perché un'altra libreria dati
Il formato Delta Lake è ottimo perché risolve i principali punti critici dell'archiviazione su file aperti. Aggiunge un log delle transazioni ACID sopra i file Parquet, la cronologia delle modifiche con la possibilità di eseguire il rollback a versioni precedenti (time travel) e un'applicazione rigorosa dello schema.
Lo stack classico attorno a Delta Lake è stato storicamente legato a Scala e Java. Se il tuo stack principale è Rust o Python leggero senza framework pesanti come PySpark, prima dell'arrivo di delta-rs, le opzioni erano limitate.
La libreria fornisce API di basso livello per Rust e un'interfaccia di alto livello per Python. Ora puoi scrivere dati con garanzie ACID su un bucket S3 o su disco locale in poche righe di codice senza avviare processi JVM.
Quick Start in Python e Rust
L'interfaccia del pacchetto Python deltalake è progettata in modo che gli sviluppatori non debbano reimparare nulla. Si integra facilmente con le librerie di analisi familiari — Pandas, Arrow o Polars.
Scrivere e leggere una tabella in Python sembra molto familiare:
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)
Un dettaglio interessante: puoi aprire istantaneamente la stessa tabella da un'applicazione Rust. Non è richiesto alcun assemblaggio manuale dei metadati. La libreria analizzerà automaticamente il log dei commit JSON nella directory _delta_log.
Esempio di lettura dei metadati della tabella 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(())
}
Sotto il cofano e integrazioni
Alta velocità e basso consumo di memoria non sono accidentali. Il progetto è costruito sopra il motore Apache Arrow e il motore vettoriale DataFusion. Rust viene utilizzato per la gestione sicura della memoria e l'I/O parallelo quando si lavora con l'archiviazione cloud.
La libreria può lavorare direttamente con AWS S3, Google Cloud Storage, Azure Blob Storage e il file system locale.
Grazie alla base condivisa su Rust e Arrow, delta-rs è rapidamente diventato parte dell'ecosistema moderno di elaborazione dati. Gli strumenti popolari funzionano con esso out of the box:
- Polars utilizza delta-rs per la lettura e scrittura diretta di tabelle Delta.
- DuckDB può eseguire query SQL analitiche sui log Delta.
- Da, Dask e Ray utilizzano questo modulo per l'elaborazione distribuita dei dati in Python.
- AWS SDK for Pandas lo utilizza come motore nativo per il formato Delta.
Casi d'uso pratici
In quali situazioni delta-rs vince rispetto all'approccio classico?
Il primo caso è l'architettura a microservizi. Ad esempio, hai un servizio in Rust o Python che raccoglie eventi da una coda di messaggi e deve aggiungere batch a un archivio dati ogni cinque minuti. Avviare un cluster Spark per questo è costoso e complesso da mantenere. Con delta-rs, il servizio semplicemente collega la libreria e scrive i dati direttamente su S3.
Il secondo caso sono le pipeline ETL leggere. Se i tuoi volumi di dati sono misurati in decine o centinaia di gigabyte, Polars combinato con delta-rs li elaborerà su una singola istanza più velocemente di quanto un cluster PySpark possa essere provisioning.
Il terzo caso è l'architettura Serverless. Nelle funzioni AWS Lambda con limiti rigorosi sulla dimensione dell'immagine e sul tempo di avvio, inserire un ambiente Java è problematico. Un binario Rust compilato con delta-rs si avvia in millisecondi.
Il progetto ha limitazioni? Sì, la specifica Delta Lake è piuttosto estesa e viene costantemente aggiornata da Databricks. Alcune funzionalità rare o nuove del formato vengono implementate in delta-rs con un leggero ritardo. Prima di utilizzare operazioni complesse come MERGE con condizioni specifiche, dovresti controllare la tabella delle funzionalità supportate nella documentazione del progetto.
Conclusione
Il team di delta-io ha fatto un ottimo lavoro. La libreria nativa Rust ha riportato la leggerezza nel lavoro con il formato Delta Lake.
Se hai bisogno di atomicità delle transazioni, versioning dei dati e archiviazione affidabile sopra Parquet, ma non vuoi avere a che fare con l'infrastruttura Java, dai sicuramente un try a delta-rs. Puoi installare il pacchetto in Python con il comando pip install deltalake e aggiungerlo a un progetto Rust tramite cargo add deltalake.
Progetti correlati