Blog
Die richtige Wahl treffen: Flink oder Kafka Streams?

Einführung
Viele Teams stehen vor der Frage: "Sollten wir Flink oder Kafka Streams verwenden, wenn wir ein neues Projekt mit Echtzeit-Streaming-Anforderungen starten?"
In diesem Beitrag möchte ich Ihnen eine Hilfestellung geben und Sie dabei unterstützen, eine fundierte Entscheidung auf der Grundlage praktischer Faktoren zu treffen. Dieser Vergleich kann auch nützlich sein, wenn Sie den Wechsel von einer Engine zu einer anderen erwägen.
Um dies richtig zu tun, werden wir beide Motoren in mehreren wichtigen Dimensionen untersuchen.
Haftungsausschluss: Dieser Artikel setzt eine gewisse anfängliche Vertrautheit mit mindestens einer der beiden Technologien voraus - entweder Flink oder Kafka Streams. Ziel ist es nicht, die Grundlagen zu vermitteln, sondern vielmehr die tieferen architektonischen Unterschiede und Kompromisse hervorzuheben, die nicht immer auf den ersten Blick ersichtlich sind.
Im Kern besteht die Aufgabe einer Streaming-Engine darin, robuste Tools für die Verarbeitung zustandsabhängiger und zeitgerechter Operationen über kontinuierliche Ereignisströme bereitzustellen. Zunächst werden wir uns ansehen, welche Zeitmechanismen die einzelnen Engines bieten und dann untersuchen, wie sie den Status verwalten. Wir fahren fort mit den Bereitstellungs- und Orchestrierungsfunktionen und betrachten schließlich ihre Flexibilität und die sie umgebenden Ökosysteme.
Dann werden wir uns ansehen, welche Einsatzmöglichkeiten sie bieten und wie Sie sie orchestrieren können. Außerdem erfahren Sie, wie vielseitig und flexibel sie sind und was das Ökosystem um sie herum ist.
Ähnlichkeiten
Lassen Sie uns zunächst die Gemeinsamkeiten zwischen Flink und Kafka Streams skizzieren - denn davon gibt es eine ganze Menge. Beide Frameworks haben gemeinsame Konzepte und eine ähnliche Art, Ihre Streaming-Topologie zu strukturieren. Sie definieren einen gerichteten azyklischen Graphen mit mehreren Quellen und Senken in jedem.
Auch ihre programmatischen APIs haben viele Gemeinsamkeiten. Sie arbeiten mit High-Level-Operationen wie keyBy, map, flatMap, Aggregationen, Windowing, Joins, Unions und mehr. Beide unterstützen die Möglichkeit, Datenströme auf ausdrucksstarke und komponierbare Weise zu kombinieren und zu transformieren.
Für fortgeschrittene Anwendungsfälle bieten beide Low-Level-APIs - Flink bietet die ProcessFunction, während Kafka Streams eine Processor-API zur Verfügung stellt. Apropos APIs: Es gibt Unterschiede in der Handhabung des Operator-Status, aber dazu komme ich später noch.
Beide bieten auch SQL-Schichten für die Stream-Verarbeitung auf höherer Ebene, was für Teams, die einen Teil der imperativen Logik abstrahieren möchten, nützlich sein kann.
Und schließlich verwenden beide RocksDB als eines der State-Backends für die skalierbare, lokale State-Speicherung.
In diesem Artikel möchte ich mich jedoch auf die grundlegenden Unterschiede konzentrieren - die Unterschiede, die die Architektur prägen und die langfristige Wartbarkeit und Flexibilität beeinflussen. Wir werden uns nicht mit dem beschäftigen, was Werner Herzog die "Wahrheit des Buchhalters" nennen würde. Stattdessen werden wir uns darauf konzentrieren, worauf es beim Aufbau zuverlässiger, skalierbarer Streaming-Systeme wirklich ankommt.
Zeit
Das grundlegendste Konzept bei der Stream-Verarbeitung ist der Begriff der Zeit, insbesondere der logischen Zeit, die oft auch als Ereigniszeit bezeichnet wird. Dieses Konzept abstrahiert von der Wanduhrzeit. Stattdessen bestimmen die Zeitstempel der Ereignisse selbst das Fortschreiten der Zeit. Mit anderen Worten: Es sind die Daten, die die Uhr vorwärts treiben.
Sie können sich das in etwa so vorstellen wie Lamports logische Uhr: Wenn keine neuen Ereignisse eintreffen, steht die Zeit still.
Flink und Kafka Streams gehen an dieses Konzept unterschiedlich heran.
Kafka Streams und Stream Time
Kafka Streams verwendet ein Konzept namens Stream Time, das als maximaler Zeitstempel eines Ereignisses definiert ist, das bisher beobachtet wurde. Es ist ein einfaches und intuitives Modell: Die Zeit schreitet nur voran, wenn neue Ereignisse mit späteren Zeitstempeln eintreffen.
Diese enge Kopplung von Zeit- und Ereignisfluss führt jedoch zu Einschränkungen. Wenn ein Operator die meisten Ereignisse herausfiltert, kann die Stream-Zeit ins Stocken geraten, was zu Problemen bei zeitbasierten Operationen wie Windowing führt. Da keine neuen Zeitstempel beobachtet werden, kann Kafka Streams die Streamzeit nicht vorverlegen. Dies kann in Szenarien, in denen einer Ihrer Operatoren aggressiv Ereignisse herausfiltert, sehr problematisch sein. Dies hält nachgelagerte Operatoren davon ab, Fenster freizugeben, da sie nicht in der Lage sind, den Zeitfortschritt zu erkennen.
Flink und Wasserzeichen
Flink hingegen führt Wasserzeichen ein - spezielle Zeitmarkierungen, die unabhängig voneinander durch den Datenstrom fließen. Sie basieren zwar immer noch auf Zeitstempeln von Ereignissen, aber sie fließen unabhängig durch den Datenstrom.
Diese Entkopplung löst das Problem von Kafka Streams. Selbst wenn keine Ereignisse einen bestimmten Operator durchlaufen, kann Flink die Zeit über Wasserzeichen weiter vorantreiben. Dies ermöglicht es auch, inaktive Quellen elegant zu behandeln, indem es Leerlaufmarkierungen aussendet und so sicherstellt, dass nachgelagerte Operatoren nicht warten müssen.
Staat
Die Arbeit mit unbegrenzten Daten bedeutet, dass Sie einen Status benötigen. Mit anderen Worten: Sie müssen sich daran erinnern, was vorher passiert ist. Der Status ist eine Erinnerung an vergangene Ereignisse - und dieser Status muss skalierbar sein. Sowohl Flink als auch Kafka Streams verwenden RocksDB, um den lokalen Status zu verwalten, wenn er den Speicherplatz übersteigt. Aber dieser Status ist flüchtig - er muss durch eine dauerhafte Speicherschicht gesichert werden. Es ist sehr üblich, Gigabytes an Speicher für den Verarbeitungsstatus über Worker Nodes zu verteilen. Dieser Speicher muss skalierbar sein.
Kafka Streams Zustandssicherung
Kafka Streams speichert Statusänderungsprotokolle in Kafka-Themen. Dieser Ansatz hat den Vorteil, dass zusätzliche externe Abhängigkeiten vermieden werden. Allerdings ist er mit erheblichen architektonischen Kompromissen verbunden.
Durch die enge Kopplung von Rechen- und Speicherkapazität innerhalb von Kafka erben Sie alle betrieblichen Komplexitäten von Kafka: Rebalancing des Brokers, Neuzuweisung von Partitionen, Skalierungsprobleme und erhöhte Belastung des Kafka-Clusters, wenn die Arbeitslast der Stream-Verarbeitung wächst.
Flink State Backing
Flink sichert seinen Zustand in einem entfernten Speicher, typischerweise Amazon S3, HDFS oder einem anderen verteilten Dateisystem. Diese Trennung sorgt für weniger Wartung und geringere Kosten. Darüber hinaus ist die neue Funktion von Flink's - Disaggregierter Zustand und ForSt State Backend einige Speicherbeschränkungen von Cloud Native Implementierungen auf.
Disaggregated State und das ForSt-Backend wurden entwickelt, um große State-Workloads Cloud-freundlicher zu machen.
Dies ist besonders wichtig für lang laufende Aufträge mit großen verschlüsselten Zuständen, wie z.B. sitzungsbasierte Analysen oder Enrichment-Anwendungsfälle. Ohne den disaggregierten Status wird die Skalierung dieser Aufträge mühsam. Stellen Sie sich all die Szenarien vor, in denen Sie Ihre Streaming-Architektur neu erfinden mussten, weil Sie durch den lokalen Speicher für TaskManager eingeschränkt waren.
Insgesamt verbessert sich die Wartbarkeit, wenn die Zustandsverwaltung entkoppelt und ausgelagert wird. Sie erhalten eine schnellere Wiederherstellung und die Freiheit, die Rechennutzung zu optimieren - alles Dinge, die viel schwieriger zu erreichen sind, wenn Ihr Zustand in der Ausführungsschicht eingeschlossen ist.
Einsatz und Betrieb
Wenn Sie keinen vollständig verwalteten Service nutzen und Ihre Streaming-Engine selbst betreiben müssen, werden die Bereitstellung und der Betrieb kritisch.
Kafka Streams Einfachheit (und Kompromisse)
Kafka Streams ist lediglich eine Bibliothek, die sich leicht in Ihre Anwendung integrieren lässt - es handelt sich lediglich um eine Java-Bibliothek, die Sie in Ihren Anwendungscode einbetten. Sie setzen keinen Kafka Streams-"Cluster" ein - stattdessen ist Ihre Anwendung der Verarbeitungsknoten. Aber diese Einfachheit hat ihren Preis - viele der Aufgaben werden auf Ihre Schultern gelegt.
Dieses reine Bibliotheksmodell kann den Betrieb von Kafka Streams im großen Maßstab schwierig machen, insbesondere in Produktionsumgebungen. Nehmen Sie zum Beispiel so etwas Grundlegendes wie die Ausnahmebehandlung. Kafka Streams bietet nur einen grundlegenden Mechanismus: den StreamsUncaughtExceptionHandler, mit dem Sie entscheiden können, ob der Thread, bei dem eine Ausnahme aufgetreten ist, ersetzt, ein Client heruntergefahren oder die gesamte Anwendung beendet werden soll.
Es gibt jedoch keine integrierte Möglichkeit, eine fein abgestufte Neustartstrategie mit Wiederholungsversuchen, Backoff-Intervallen oder Fallback-Logik zu konfigurieren. Natürlich werden Sie eine zentrale Fehlerbehandlung vermissen. Jede Instanz ist für sich selbst verantwortlich. Es gibt keinen externen Controller, der Aufträge umplanen oder neu starten kann. Sie müssen sich im Grunde selbst um all das kümmern.
Die Laufzeit von Flink
Flink ist ein vollwertiges Framework für die verteilte Datenverarbeitung. Flink verfügt über eine spezielle Laufzeitarchitektur, die auf JobManagern und TaskManagern basiert. JobManager: Das Herzstück einer Flink-Bereitstellung ist für die Auftragsplanung, die Checkpoint-Koordination, die Fehlerbehebung und die allgemeine Ressourcen-Orchestrierung zuständig. Das Flink-Ökosystem bietet native Orchestrierungs-Tools, einschließlich hervorragender Kubernetes-Unterstützung über den Flink Kubernetes Operator.
Dies ermöglicht fortschrittliche Funktionen wie automatische Skalierung mit fein abgestimmter Ressourceneinstellung und gute Unterstützung für Operationen.
Abschließende Gedanken und Worte zur Vielseitigkeit
Wie Sie vielleicht bemerkt haben, hat Flink in allen Aspekten, die wir mit Kafka Streams verglichen haben, die Nase vorn. Aber ich möchte keinen falschen Eindruck von Kafka Streams erwecken - ich halte es für ein großartiges Tool. Es gibt Bereiche, in denen Kafka Streams meiner Meinung nach Dinge besser macht. Ein bemerkenswertes Beispiel ist die KTable-Abstraktion, die sich natürlicher und intuitiver anfühlt als die Verwaltung des Status in Flink. In Kafka Streams bietet KTable eine klare, übersichtliche Darstellung eines Changelog-Streams als materialisierte Ansicht. Im Gegensatz dazu ist der Status in Flink eng an Operatoren gekoppelt und innerhalb der Grenzen einer bestimmten Transformation skaliert. Was mir an Kafka Streams außerdem sehr gut gefällt, ist die Einfachheit der Architektur: Es läuft ausschließlich auf Kafka und hat keine zusätzlichen Abhängigkeiten. Das kann für manche Teams ein entscheidender Vorteil sein.
Allerdings stimme ich dem oft wiederholten Argument, dass Kafka Streams viel einfacher ist als Flink, nicht ganz zu. Ehrlich gesagt finde ich Kafka Streams schwieriger und schwieriger in Produktionsumgebungen zu warten, gerade weil es eine reine Bibliothek ist. Die operative Last liegt auf Ihren Schultern.
Insgesamt ist Flink in den Szenarien, auf die wir uns konzentriert haben, einfach besser.
Am Ende könnte es auf die Vielseitigkeit ankommen. Die Flexibilität von Flink und das breitere Ökosystem, das um Flink herum aufgebaut wurde, machen es zu einem ernstzunehmenden Konkurrenten im Bereich des Streaming. Dies wird besonders wichtig, da immer mehr Architekturen ohne Kafka entstehen und Lakehouses wie Paimon in bestimmten Szenarien als Transportschicht fungieren können.
Mit Kafka Streams sind Sie bei der Arbeit mit externen Systemen im Wesentlichen an Kafka - und wahrscheinlich an Kafka Connect - gebunden. Mit Flink können Sie nativ von einer Vielzahl von Systemen konsumieren und in diese schreiben, ohne auf Kafka als Vermittler angewiesen zu sein.
Auch wenn Kafka Streams sicherlich seine guten Seiten hat - Flink bietet letztlich eine breitere und leistungsfähigere Grundlage für die Echtzeit-Datenverarbeitung in großem Maßstab. Seine Architektur, seine Flexibilität und sein reichhaltiges Ökosystem ermöglichen es, eine größere Vielfalt von Anwendungsfällen zu unterstützen, von traditionellem Streaming bis hin zu neuen Mustern, die Data Lakes und Kafka-freie Designs umfassen.
Die Entscheidung zwischen beiden hängt von den Bedürfnissen Ihres Teams, Ihrer Infrastruktur und der Komplexität Ihrer Daten-Workflows ab. Wenn Sie jedoch langfristig planen und Skalierbarkeit, Beobachtbarkeit und betriebliche Ausfallsicherheit im Auge haben, ist Flink vielleicht die zukunftssicherere Lösung.
Haben Sie Fragen oder Zweifel zu Kafka oder Flink?
Verfasst von
Juliusz Nadbereżny
Unsere Ideen
Weitere Blogs
Contact



