Bibliothek / SDK
apache/datafusion-ballista avatar
apache/datafusion-ballista

Ballista: DataFusion-Abfragen per SessionContext::standalone() auf den Cluster

Verteilte Abfrage-Engine von Apache DataFusion Ballista. Ballista führt dieselben SQL- und DataFrame-Workloads in einem Cluster mit minimalen Codeänderungen und denselben Ergebnissen aus.

2.135 Sterne320 ForksRustApache-2.0

Auf einen Blick

Was ist das?
Apache DataFusion Ballista erweitert DataFusion um verteilte Ausführung und verspricht dieselben Ergebnisse bei wenigen geänderten Codezeilen. Der Text ordnet den Umstieg, die im README genannte Kompatibilitätslücke, Scheduler- und Executor-Prozesse, die Web-TUI und die Cargo-Features ein.
Für wen ist es gedacht?
Ballista lohnt sich für Teams, die bereits DataFusion einsetzen und über eine einzelne Maschine hinausgewachsen sind, weil der Umstieg im Beispiel an einer Zeile hängt und der Rest des Codes unverändert bleibt. Es lohnt sich nicht, wenn die Abfragen auf einem Knoten ausreichend schnell laufen, und es ist riskant für Anwendungen, die auf die neuesten DataFusion-Funktionen angewiesen sind, solange die im README genannte Lücke zwischen beiden Projekten besteht.
Darf ich es kommerziell nutzen?
Ja. Apache-2.0 ist eine freizügige Lizenz: Sie dürfen darauf aufbauende Software nutzen, verändern und verkaufen, solange Sie die Urheberrechts- und Lizenzhinweise beibehalten.
Wird es noch gepflegt?
Ja. Die letzten Commits kamen vor 2 Tagen.
In welcher Sprache ist es geschrieben?
Hauptsächlich Rust, laut der Sprachstatistik von GitHub.

Die Antworten beruhen auf den GitHub-Daten des Projekts (zuletzt abgeglichen am 14. September 2026) und auf unserer Analyse. Sie sind keine Rechtsberatung.

TIEFGEHENDE OPEN-SOURCE-ANALYSE

Was Ballista an einer DataFusion-Anwendung ändert: SessionContext::standalone()

Ballista ist eine verteilte Abfrage-Engine, die Apache DataFusion um die parallele Ausführung über mehrere Knoten erweitert. Das Repository apache/datafusion-ballista führt Rust als Hauptsprache, steht unter Apache-2.0 und entwickelt auf main. Die Beschreibung bringt den Anspruch auf den Punkt: Dieselben SQL- und DataFrame-Workloads sollen über einen Cluster laufen, mit minimalen Codeänderungen und denselben Ergebnissen.

Am Beispiel im README lässt sich der Aufwand ablesen. Die Einzelknoten-Fassung beginnt mit use datafusion::prelude::* und SessionContext::new(), registriert eine CSV-Datei über ctx.register_csv("example", "tests/data/example.csv", CsvReadOptions::new()) und führt eine Abfrage wie SELECT a, MIN(b) FROM example WHERE a <= b GROUP BY a LIMIT 100 aus.

In der Ballista-Fassung kommt use ballista::prelude::* hinzu, und statt SessionContext::new() steht SessionContext::standalone().await?. Der Kontext startet damit die gesamte nötige Infrastruktur im Hintergrund. Alles andere, von der Tabellenregistrierung bis zur Ausgabe über df.show(), bleibt unverändert. Genau darin liegt der Reiz des Projekts.

Die im README genannte Lücke zwischen DataFusion und Ballista

An dieser Stelle gehört ein Warnhinweis hin, den das README selbst als wichtig markiert. Zwischen DataFusion und Ballista besteht eine Lücke, die zu Inkompatibilitäten führen kann. Die Gemeinschaft arbeitet nach eigener Angabe daran, sie zu schließen. Konkreter wird das Material nicht: Es nennt keine Liste betroffener Funktionen und keinen Zeitplan.

Für die Praxis heißt das, dass der Umstieg nicht bedingungslos ist. Eine Abfrage, die auf einem Knoten läuft, kann unter Ballista scheitern oder etwas anderes liefern, wenn sie ein Sprachmittel nutzt, das die verteilte Fassung noch nicht trägt. Wer den Schritt macht, sollte ihn deshalb mit einem Ergebnisvergleich verbinden und nicht mit der bloßen Erwartung, dass sich nichts ändert.

Zum Versionsstand: Alle drei jüngsten Releases, 53.0.0, 54.0.0 und 54.1.0, erschienen am 9. August 2026. Dieser Gleichklang deutet auf eine gemeinsame Freigabe mit dem DataFusion-Projekt hin, aus dem Material belegen lässt sich das aber nicht.

Scheduler und Executor: zwei Prozessarten im Ballista-Cluster

Ein Ballista-Cluster besteht aus einem oder mehreren Scheduler-Prozessen und einem oder mehreren Executor-Prozessen. Beide lassen sich als native Binärdateien betreiben, liegen aber auch als Docker-Images vor und können über Docker Compose oder Kubernetes ausgerollt werden. Die Aufteilung ist die klassische: Der Scheduler verteilt Arbeit, die Executor führen sie aus.

Das README beschreibt den Ablauf in zwei Richtungen. Kunden übergeben Aufträge an den Scheduler. Executor holen sich Aufgaben beim Scheduler ab und melden den Status dorthin zurück. Näheres steht im Architekturleitfaden unter docs/source/contributors-guide/architecture.md.

Wer nur ausprobieren will, muss keinen Cluster aufbauen. Das README verweist auf Beispiele im Verzeichnis examples, die es in einer Standalone- und in einer verteilten Fassung gibt, und danach auf den Einstiegsleitfaden unter ballista/client/README.md. Dieser Weg ist kurz, und er umgeht die Frage nach Container-Orchestrierung zunächst vollständig.

Web-TUI: Jobs, Executors und Metriken unter http://localhost:50050

Für die Beobachtung eines laufenden Clusters bringt Ballista eine browserbasierte Oberfläche mit. Die Web-TUI zeigt Ansichten für Aufträge, Executor, Kennzahlen und Scheduler-Informationen. Sie ist damit das Werkzeug der Wahl, wenn eine Abfrage hängt und die Frage im Raum steht, ob der Scheduler Aufgaben verteilt oder ein Executor sie nicht abholt.

Der Zugang ist denkbar einfach: Ist der HTTP-Endpunkt des Schedulers erreichbar, führt das Öffnen der Scheduler-Adresse im Browser, im README als http://localhost:50050 angegeben, unmittelbar zur gehosteten Oberfläche. Es ist also keine zusätzliche Anwendung zu installieren und keine Konfiguration zu setzen, solange der Endpunkt offen ist.

Wie sich die Oberfläche gegen unbefugten Zugriff absichern lässt, steht im Material nicht; in der Dokumentation nicht angegeben. Wer einen Scheduler auf einer erreichbaren Adresse betreibt, sollte diese Frage vorher klären, denn die Ansichten geben Auftrags- und Clusterdetails preis.

Cargo-Features von standalone bis force_hash_collisions

Optionale Funktionalität wird über Cargo-Features zugeschaltet, und die Tabellen im README sind für den Produktionsbetrieb die interessanteste Stelle. Die Client-Crate ballista aktiviert das Feature standalone standardmäßig, womit Scheduler und Executor im eigenen Prozess laufen.

In ballista-core ist arrow-ipc-optimizations voreingestellt, was die Shuffle-Leistung über Arrow-IPC verbessern soll. spark-compat schaltet einen Kompatibilitätsmodus über datafusion-spark zu, ist aber abzuwählen und damit ein bewusstes Opt-in. build-binary wird für den Bau von Binärdateien gebraucht und zieht AWS-S3-Unterstützung und Kommandozeilenverarbeitung nach sich. force_hash_collisions ist ausdrücklich als Testwerkzeug markiert und zwingt alle Werte auf denselben Hash.

Beim Scheduler ist build-binary voreingestellt, darüber hinaus lassen sich substrait für Substrait-Pläne, prometheus-metrics für die Kennzahlenabnahme, graphviz-support zur Visualisierung des Ausführungsgraphen, keda-scaler und rest-api zuschalten. Ein Bauvorschlag aus dem Material lautet cargo build -p ballista für den Standalone-Betrieb und cargo build -p ballista-scheduler --features substrait für einen Scheduler mit Substrait-Unterstützung.

Drei Zielgruppen von Spark-Umsteigern bis Engine-Bauern

Das README unterscheidet drei Gruppen, und die Unterschiede zwischen ihnen sind lehrreich. Die erste besteht aus DataFusion-Nutzern, die über eine Maschine hinausgewachsen sind; für sie ist Ballista der naheliegende nächste Schritt.

Die zweite Gruppe kommt von Spark. Für sie hält Ballista dasselbe Ausführungsmodell bereit: Pläne werden an Shuffle-Grenzen in Stufen zerlegt, jede Partition ergibt eine Aufgabe, Executor verfügen über vcores, und adaptive Abfrageausführung ist vorgesehen. Der Unterschied liegt in der Umsetzung: Rust statt JVM, und nach Angabe des README ein leichterer Unterbau, ohne dass ein neues Paradigma gelernt werden muss.

Die dritte Gruppe baut selbst eine verteilte Abfrage-Engine. Für sie sind Scheduler, Executor und Planserialisierung als Bausteine mit Erweiterungspunkten gedacht, statt verteilte Ausführung neu zu schreiben. Welche Garantien jede dieser Gruppen erwarten darf, ist im Leitfaden docs/source/contributors-guide/user-personas.md festgehalten.

Spice AI, Coralogix und wann DataFusion ohne Ballista ausreicht

Zur Verbreitung nennt das README zwei Organisationen: Spice AI, das einen Beitrag über die Nutzung veröffentlicht hat, und Coralogix. Weitere können sich per Pull Request eintragen. Das ist eine kurze Liste, und sie sagt nichts über die Zahl der Produktionseinsätze; für eine Einschätzung der Reife ist das Material an dieser Stelle dünn.

Die Alternative liegt im eigenen Haus: DataFusion ohne Ballista. Wer auf einem einzelnen Knoten bleibt, spart Scheduler- und Executor-Prozesse, Shuffle über Netz und die im README genannte Kompatibilitätslücke. Der Preis ist die Begrenzung auf die Rechenleistung einer Maschine. Ballista lohnt erst, wenn diese Grenze erreicht ist.

Als falsches Werkzeug erscheint Ballista in zwei Fällen. Erstens bei Abfragen, die auf einem Knoten schnell genug sind, weil dort die Betriebskosten eines Clusters ohne Gegenwert bleiben. Zweitens bei Anwendungen, die auf dem neuesten DataFusion-Stand aufbauen; die genannte Lücke wirkt dort unmittelbar. Zur unterstützten SQL-Breite verweist das Material auf die DataFusion-Dokumentation und führt als Beispiele CTEs, Joins und Unterabfragen an, nicht aber eine vollständige Liste.

Redaktionelles Fazit

Ballista lohnt sich für Teams, die bereits DataFusion einsetzen und über eine einzelne Maschine hinausgewachsen sind, weil der Umstieg im Beispiel an einer Zeile hängt und der Rest des Codes unverändert bleibt. Es lohnt sich nicht, wenn die Abfragen auf einem Knoten ausreichend schnell laufen, und es ist riskant für Anwendungen, die auf die neuesten DataFusion-Funktionen angewiesen sind, solange die im README genannte Lücke zwischen beiden Projekten besteht. Vor der Entscheidung sollte dieselbe Abfrage einmal mit SessionContext::new() und einmal mit SessionContext::standalone() gegen denselben Datenbestand laufen und das Ergebnis zeilenweise verglichen werden; was dabei abweicht, fällt unter genau diese Lücke.

Offizielle Quellen

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Community-Notizen

Community-Notizen