Artikel

Apache Fluss: Na super, schon wieder ein Tool, das alles verändert

Warum das Streaming Lakehouse diesmal vielleicht nicht nur ein Buzzword ist – und was kolumnares Streaming-Storage für ML-Pipelines und AI Coding Agents bedeutet.

7 Min. Lesezeit Martin Stagl
Data Engineering Streaming Apache Flink Lakehouse ML

Apache Fluss: Na super, schon wieder ein Tool, das alles verändert

Warum das „Streaming Lakehouse” diesmal vielleicht nicht nur ein Buzzword ist – und was das für ML-Pipelines und AI Coding Agents bedeutet.


Wer im Data-Engineering-Umfeld arbeitet, kennt das Muster: Alle 18 Monate erscheint ein neues Open-Source-Projekt, das endlich – diesmal wirklich, ehrlich – die Lücke zwischen Streaming und Analytics schließt. Die Slides auf der Flink Forward sind immer beeindruckend. Die Architektur-Diagramme sehen aus wie aus einem Lehrbuch. Und sechs Monate später kämpft man mit JAR-Konflikten und fragt sich, warum der Tiering-Job schon wieder hängt.

Apache Fluss (Incubating) tritt genau in diese Arena. Noch ein Tool. Noch ein Versprechen. Noch ein deutsches Wort im Apache-Namespace – „Fluss”, wie Fluss, ausgesprochen /flʊs/. Daten fließen wie ein Fluss in den See. Poetisch. Schauen wir uns an, ob dahinter mehr steckt als Marketing.

Was Fluss eigentlich ist (und was nicht)

Fluss ist kein Stream Processor. Es ist kein Kafka-Ersatz im engeren Sinne. Es ist auch kein Lakehouse-Format. Fluss positioniert sich als Streaming Storage Layer – eine Schicht, die zwischen der Compute Engine (primär Apache Flink) und dem Lakehouse (Iceberg, Paimon, Lance) sitzt. Die zentrale Idee: Daten werden in einem kolumnaren Format auf Basis von Apache Arrow gespeichert, mit Sub-Sekunden-Latenz geschrieben und gelesen, und automatisch ins Lakehouse ge-tiered.

Das klingt erstmal wie „Kafka mit Parquet-Ambitionen”, ist aber architektonisch ein anderer Ansatz. Fluss unterscheidet zwei Tabellentypen:

  • Log Tables – Append-only, klassisches Event-Log, vergleichbar mit einem Kafka-Topic, aber kolumnar gespeichert. Streaming Column Pruning inklusive: Die Engine liest nur die Spalten, die sie braucht.
  • PrimaryKey Tables – Upsert-fähig, mit RocksDB-basiertem KV-Index für High-QPS Lookups. Das ist die Dimension-Tabelle, die man bisher in Redis oder Cassandra vorhalten musste, nur dass sie jetzt im selben System lebt.

Dazu kommt der Tiering Service: Ein Hintergrundprozess, der kontinuierlich Daten aus dem Hot Layer (Fluss, NVMe/SSD, Sub-Sekunden-Latenz) in den Cold Layer (Iceberg/Paimon/Lance, Object Storage, Minuten-Latenz) überführt. Parquet-Dateien, Compaction, Snapshot-Management – alles automatisch. Und der Clou: Union Reads. Eine Query liest nahtlos Hot- und Cold-Daten zusammen, ohne Duplikate, ohne Lücken.

Das eigentliche Problem, das Fluss löst

Man muss ehrlich sein: Die meisten „Streaming Lakehouse”-Architekturen der letzten Jahre waren im Kern ein Kompromiss. Iceberg, Delta Lake und Paimon sind fantastische Formate für analytische Workloads. Aber sie basieren auf Dateien in Object Storage. Und Dateien committen, Metadaten schreiben, S3-Consistency abwarten – das dauert. Egal wie schnell man die Commit-Intervalle dreht, unter einer Minute kommt man realistisch nicht. Und wenn man es versucht, handelt man sich ein Small-File-Problem ein, das den nächsten Compaction-Job zum Albtraum macht.

Fluss adressiert genau dieses Dilemma: Man muss sich nicht mehr zwischen niedriger Latenz und effizienten Reads entscheiden. Der Hot Layer liefert Millisekunden-Freshness für die Fälle, die es brauchen (Fraud Detection, Recommendation Engines, operative Dashboards). Der Cold Layer liefert komprimierte Parquet-Files für die analytischen Workloads, die sowieso mit Minuten-Granularität arbeiten.

Das Data Layout ist dabei aligned: Partitions und Buckets sind in beiden Layern identisch. Arrow-zu-Parquet-Konvertierung passiert ohne Netzwerk-Shuffle. Das klingt nach einem Detail, ist aber in der Praxis der Unterschied zwischen „funktioniert” und „wir brauchen drei Extra-Flink-Jobs für die Reorganisation”.

Delta Joins: Wo es wirklich interessant wird

Das Feature, bei dem ich hellhörig geworden bin, sind die Delta Joins mit Flink. Das klassische Problem bei Stream-Stream-Joins in Flink: Der State wächst. Und wächst. Und wächst. Checkpoints werden langsamer, Restores dauern ewig, und irgendwann hat man 100 TB State in RocksDB, die bei jedem Checkpoint über das Netzwerk geschoben werden.

Delta Joins externalisieren den State in Fluss-Tabellen. Flink joint nur noch auf den Deltas – den Änderungen seit dem letzten Batch. Kein State-Bootstrapping, kein explodierender Checkpoint. Die Zahlen, die Alibabas Search-&-Recommendation-Team berichtet: CPU- und Memory-Verbrauch um 80% reduziert, Checkpoint-Dauer von 90 Sekunden auf eine Sekunde, über 100 TB State eliminiert. Man darf skeptisch sein bei Vendor-Benchmarks, aber die Größenordnung ist beeindruckend.

Beispiel: Fluss-Cluster mit Docker Compose

Für einen ersten Test reicht folgende docker-compose.yml:

services:
  zookeeper:
    image: zookeeper:3.9.2
    restart: always

  coordinator-server:
    image: apache/fluss:0.8.0-incubating
    command: coordinatorServer
    depends_on:
      - zookeeper
    environment:
      - |
        FLUSS_PROPERTIES=
        zookeeper.address: zookeeper:2181
        bind.listeners: FLUSS://coordinator-server:9123
        remote.data.dir: /tmp/fluss/remote-data
    ports:
      - "9123:9123"

  tablet-server:
    image: apache/fluss:0.8.0-incubating
    command: tabletServer
    depends_on:
      - coordinator-server
    environment:
      - |
        FLUSS_PROPERTIES=
        zookeeper.address: zookeeper:2181
        bind.listeners: FLUSS://tablet-server:9123
        tablet-server.id: 0
        kv.snapshot.interval: 0s
        data.dir: /tmp/fluss/data
        remote.data.dir: /tmp/fluss/remote-data
    volumes:
      - shared-tmpfs:/tmp/fluss

volumes:
  shared-tmpfs:
    driver: local
    driver_opts:
      type: tmpfs
      device: tmpfs

Das ist ein minimales Setup – ein CoordinatorServer, ein TabletServer, ZooKeeper als Metastore. Für ein Streaming-Lakehouse mit Iceberg-Tiering kommen noch ein Flink-Cluster und ein S3-kompatibler Object Store dazu (RustFS im Dev-Setup, MinIO oder echter S3 in Produktion).

Tabellen anlegen geht dann per Flink SQL:

-- Log-Tabelle für Events
CREATE TABLE sensor_events (
    sensor_id STRING,
    temperature DOUBLE,
    humidity DOUBLE,
    event_time TIMESTAMP(3)
) WITH (
    'bucket.num' = '4'
);

-- PrimaryKey-Tabelle für Stammdaten
CREATE TABLE sensor_metadata (
    sensor_id STRING,
    location STRING,
    model STRING,
    PRIMARY KEY (sensor_id) NOT ENFORCED
) WITH (
    'bucket.num' = '2'
);

-- Lakehouse-Tiering aktivieren
CREATE TABLE sensor_events_lakehouse (
    sensor_id STRING,
    temperature DOUBLE,
    humidity DOUBLE,
    event_time TIMESTAMP(3)
) WITH (
    'bucket.num' = '4',
    'table.datalake.enabled' = 'true'
);

Was das für AI Coding Agents bedeutet

Jetzt wird es spannend. AI Coding Agents – ob Claude Code, Cursor, Windsurf oder was auch immer gerade die nächste „Revolution” ist – haben ein gemeinsames Problem: Sie operieren auf Snapshots. Der Agent bekommt den aktuellen Code, generiert Änderungen, und hofft, dass sich in der Zwischenzeit nichts Relevantes geändert hat. In einer Welt, in der Deployment-Pipelines, Monitoring-Alerts und Business-Metriken ständig fließen, ist das eine fragile Annahme.

Ein Streaming Storage wie Fluss könnte hier als kontextueller Backbone dienen. Statt dem Agent einen statischen Snapshot zu geben, subscribt er auf einen Changelog: Code-Änderungen, CI/CD-Events, Fehlerraten, Feature-Flag-Updates – alles als kontinuierlicher Stream. Der Agent reagiert nicht auf Prompts, sondern auf Zustandsänderungen. Das ist ein Paradigmenwechsel von „frag den Agent” zu „der Agent beobachtet und handelt”.

Praktisch vorstellbar: Ein Flink-Job enriched Code-Change-Events mit Metriken aus dem Monitoring, schreibt das Ergebnis in eine Fluss-Tabelle, und ein nachgelagerter Agent-Service liest per Subscription die relevanten Deltas. Latenz: Unter einer Sekunde. Der Agent weiß, dass die Fehlerrate nach dem letzten Deployment gestiegen ist, noch bevor jemand ins Grafana schaut.

Real-Time ML: Vom Feature Store zum Context Store

Für ML-Pipelines ist der Impact direkter. Das Training-Serving-Skew-Problem – Features werden offline mit Batch-Pipelines berechnet, aber online mit anderer Logik bereitgestellt – ist ein bekannter Killer für Modellqualität in Produktion. Feature Stores wie Feast oder Tecton existieren genau deshalb.

Fluss geht einen Schritt weiter und positioniert sich als Context Store: nicht nur strukturierte Features, sondern auch Entity-State, Event-Sequenzen, historische Daten für Rekonstruktion und – durch die Lance-Integration – auch Embeddings und Vektoren. Alles aus einem System, mit derselben Semantik für Training und Serving.

Konkret heißt das:

  • Real-Time Feature Serving: PrimaryKey-Tabelle in Fluss als Online-Store mit Millisekunden-Lookup. Kein separates Redis, kein DynamoDB.
  • Training Data: Derselbe Datenstrom, über Iceberg ge-tiered, als Parquet-Files für Spark oder PyTorch. Gleiche Semantik, kein Skew.
  • Multimodal AI: Über die Lance-Integration können Bilder, Text und Embeddings in Echtzeit gestreamt und für RAG-Systeme verfügbar gemacht werden.

Ob man das in der DACH-Region so bauen würde? Kommt drauf an. Die meisten Unternehmen hier kämpfen noch damit, ihre Batch-Pipelines zuverlässig zum Laufen zu bringen. Aber für die, die tatsächlich Real-Time-ML betreiben – Ad-Tech, Finanzdienstleister, Industrieautomatisierung – ist das eine relevante Architektur-Option.

Nüchterne Einordnung

Apache Fluss ist noch im Incubator-Status. Version 0.8 ist der erste offizielle ASF-Release. Flink-Integration funktioniert, Spark und StarRocks sind angekündigt aber noch nicht GA. Die Dokumentation ist solide für ein Incubating-Projekt, aber dünn verglichen mit etablierten Tools. Der Python-Client existiert als Alpha auf Basis eines Rust-Bindings, aber ist noch nicht offiziell released.

Was positiv auffällt: Das Projekt kommt von Alibabas Flink-Team (Jark Wu, einer der Köpfe hinter Flink CDC und Flink SQL, ist Gründer). Ververica pushed die kommerzielle Adoption. Die Architektur ist durchdacht – Arrow-basiert, Compute-Storage-Separation, Delta Joins – das sind keine Spielereien, sondern Antworten auf reale Probleme, die jeder kennt, der mal 50 TB Flink-State verwaltet hat.

Was fehlt: Production-Erfahrungsberichte außerhalb von Alibaba. DSGVO-relevante Deployment-Patterns (On-Prem, EU-Cloud). Multi-Tenancy. Und die Frage, ob ZooKeeper als Metastore wirklich die Zukunft ist – denn Kafka hat gerade schmerzhaft gelernt, dass Raft die bessere Wahl ist.

Fazit: Beobachten, nicht ignorieren

Ja, es ist „schon wieder ein Tool”. Ja, das Streamhouse-Branding ist Marketing. Aber die technischen Konzepte – kolumnares Streaming-Storage, automatisches Tiering, Delta Joins, Union Reads – lösen echte Probleme, die mit der aktuellen Kafka+Flink+Iceberg-Architektur nur mit viel Duct Tape und Hoffnung adressierbar sind.

Für den DACH-Raum gilt: Wer heute Flink im Einsatz hat und mit State-Management, Small-File-Problemen oder der Latenz-Lücke zwischen Streaming und Analytics kämpft, sollte Fluss auf die Watchlist setzen. Wer gerade erst seine erste Batch-Pipeline stabilisiert hat, kann ruhig noch warten.

Und für die AI-Fraktion: Die Idee, dass Coding Agents und ML-Modelle auf einem kontinuierlichen, kolumnaren, semantisch konsistenten Datenstrom operieren statt auf Snapshots und REST-APIs, ist keine Science Fiction. Fluss liefert das Storage-Fundament dafür. Ob die Agent-Frameworks das in den nächsten 12 Monaten auch tatsächlich nutzen, steht auf einem anderen Blatt.

Aber hey – wenigstens hat das Projekt einen ehrlichen deutschen Namen. Ein Fluss fließt halt. Ob er auch ankommt, werden wir sehen.


Martin Stagl ist Data Scientist & Systems Engineer in Wien. Er betreibt stagl.systems als technischen Blog für IT-Entscheider im DACH-Raum.

Martin Stagl

Martin Stagl

Systems Engineer & Data Architect · Wien

Share: