Apache Kafka hat sich seit seiner Open-Source-Veröffentlichung als der industrielle Standard im Bereich verteilter Messaging-Systeme etabliert. Ursprünglich für den Einsatz in lokalen Rechenzentren konzipiert, begegnet Kafka immer häufiger den Herausforderungen moderner Cloud-Umgebungen. Insbesondere wenn Kafka auf Cloud-native Speicherlösungen wie Amazon S3 zugreifen soll, treten erhebliche technische Hürden auf. Die Kopplung von Rechenleistung und Speicher, Replikationsmechanismen und Latenzanforderungen stehen dabei im Fokus der Probleme. Der Wunsch, Kafka-Daten in kostengünstigem Objektspeicher abzulegen, ist vor allem durch Effizienz und Skalierbarkeit motiviert.
Traditionelle Kafka-Architekturen verbinden Speicher und Rechenkapazitäten eng miteinander, was die Skalierung der Speicherung aufwändig und teuer macht. Zudem sind für Datensicherheit und Ausfallsicherheit Mechanismen wie Replikation notwendig, die in der Cloud aber mit hohen Kosten für Datenübertragungen zwischen Verfügbarkeitszonen verbunden sind. Amazon S3 als Objektspeicher verspricht hier Einsparungen, da es günstiger und hochverfügbar ist, allerdings auf Kosten der direkten Dateizugriffsperformance. Der Hauptnachteil von S3 liegt im vergleichsweise hohen Zugriffs-Latenzen. Während lokale SSDs Zugriffe in Mikrosekunden ermöglichen, liegen die Zugriffszeiten bei S3 im Millisekundenbereich.
Das bedeutet eine Verzögerung um den Faktor Tausend, was sich sofort auf den Durchsatz und die Reaktionszeiten von Kafka auswirkt. Um trotzdem eine niedrige Latenz beim Schreiben von Nachrichten sicherzustellen, setzen Lösungen wie AutoMQ auf eine Kombination aus einem Write Ahead Log (WAL) auf schnellerem Speicher, etwa AWS EBS, und asynchroner Speicherung in S3. Nachrichten werden zunächst im WAL festgehalten und erst später im Hintergrund in S3 abgelegt. Damit wird eine Antwort an den Producer deutlich schneller ermöglicht, ohne die Haltbarkeit der Daten zu gefährden. Die Anzahl der Operationen im Objektspeicher ist ein weiterer entscheidender Kostenfaktor.
Amazon verlangt beispielsweise Gebühren pro PUT-Anfrage, was bei sehr vielen kleinen Schreibvorgängen schnell ins Geld gehen kann. Um diesen Kostenblock zu reduzieren, werden Daten grundsätzlich gebündelt beziehungsweise gepuffert, bevor sie als größere Objekte in S3 abgelegt werden. Dabei entstehen unterschiedliche Objektarten, die zum Beispiel auf einzelne Partitionen oder mehrere Streams verteilt sind. Nachteilig ist allerdings, dass Daten einer Partition so auf mehrere Objekte verteilt werden können, was beim Lesen zu erhöhten Zugriffsanforderungen führt und die Performance drosselt. Um dem entgegenzuwirken, nutzen moderne Kafka-Kompatible Systeme Kompaktierungsprozesse, die kleinere Objekte zu größeren konsolidieren und somit die Anzahl der Zugriffe reduzieren.
Caching ist ein essenzieller Bestandteil für die Realisierung akzeptabler Leseleistung auf Objektspeichern. Durch intelligente Cache-Strategien werden häufig genutzte oder aktuelle Daten im Arbeitsspeicher der Broker vorgehalten, was die Anzahl der Zugriffe auf S3 signifikant mindert. Die Herausforderung besteht jedoch darin, den Cache effizient zu verwalten und bei Bedarf zu invalidieren. AutoMQ nutzt zum Beispiel zwei getrennte Caches: einen Log-Cache für aktuelle Daten und einen Block-Cache für historische Daten. Dieses System ermöglicht eine gute Balance zwischen Performance und Ressourcennutzung.
Die Verwaltung von Metadaten fällt in einer Umgebung mit Objektspeicher anders aus als bei klassischen Datei- oder Blockspeichern. Kafka ist es gewohnt, Metadaten aus dem Dateisystem zu lesen, während die S3-Umgebung häufig LIST-Anfragen erfordert, die aber in Performance und Kosten nachteilig sind. Um die Menge der Metadaten zumindest zu begrenzen, sind Kompaktierungsstrategien und eine kluge Strukturierung der Datenobjekte unverzichtbar. Diese Metadaten enthalten essenzielle Informationen über Partitionen, Segmente und Offset-Mappings und müssen jederzeit konsistent und schnell verfügbar sein. Ein weiteres Thema bei der Integration von Kafka und S3 ist die Kompatibilität.
Kafka-Protokolle und -Mechanismen setzen lokal gespeicherte Logs voraus, die sequenziell beschrieben werden können. Das ist mit Objektspeichern nicht ohne Weiteres möglich, da diese keine Append-Operation auf bestehenden Objekten unterstützen. Um dennoch Kafka-Kompatibilität sicherzustellen, müssen innovative Abstraktionen geschaffen werden. AutoMQ etwa ersetzt das klassische Kafka-Log durch ein neu konzipiertes Stream-Abstrakt, das Basisoperationen wie Anhängen und Lesen von Daten mit dem Backend Objektspeicher abbildet. Durch dieses Design kann AutoMQ trotz Fundamentaldifferenzen im Speichermodell nahezu vollständige Kompatibilität bewahren, was den Umstieg für Anwender erleichtert.
Bei der Bereitstellung in der Cloud spielt auch die Datenlokalität eine wichtige Rolle. Im herkömmlichen Kafka-Modell sind Partitionen an bestimmte Broker gebunden, was sowohl aus Sicht der Leistung als auch der Ausfallsicherheit Vorteile bringt. Cloud-Objektspeicher erlauben grundsätzlich einen „shared disk“-ähnlichen Zugriff auf die Daten, so dass theoretisch jeder Broker jede Partition lesen oder beschreiben könnte. AutoMQ verfolgt trotzdem weiterhin ein Modell mit Datenlokalität und sorgt dafür, dass bestimmte Broker für definierte Partitionen zuständig bleiben. Damit bleiben Konzepte wie Load-Balancing und Partitionsverantwortlichkeit erhalten.
Neben der Architektur ist das Netzwerk- und insbesondere das Kostenmanagement für die Cross Availability Zone (AZ)-Datenübertragung essenziell. Klassische Kafka-Setups verursachen durch die Verteilung der Leader über verschiedene AZs hohe AWS-Transferkosten, da Nachrichten vom Producer zur Leader-Partition und dann auch noch repliziert werden müssen. Die Benutzung von S3 als gemeinsamer Speicher eliminiert viele dieser Replikationskosten, da der Objektspeicher selbst für Datenhaltbarkeit sorgt. Das Problem der Producer, die in einer anderen AZ als der Partition-Leader sind, bleibt jedoch bestehen. Lösungen wie AutoMQ adressieren dieses durch spezielle Konsistenzmechanismen und Routing, die es ermöglichen, dass der Producer stets zuerst mit einem lokal in der AZ befindlichen Broker kommuniziert.
Dieser Broker schreibt die Daten dann temporär in S3 und informiert im Hintergrund den tatsächlichen Partition-Leader, wodurch der meiste Datenverkehr innerhalb derselben Verfügbarkeitszone verbleibt. Zusammenfassend ergeben sich also eine Reihe komplexer technischer Herausforderungen, wenn man eine Kafka-kompatible Messaging-Plattform auf Objektspeicher wie S3 aufbauen will. Dabei müssen Latenzanforderungen, Kosten für API-Anfragen, Daten- und Metadatenorganisation, Kompatibilität mit Kafka-Protokollen sowie Cloud-spezifische Themen wie AZ-Kosten berücksichtigt und bewusst gegeneinander abgewogen werden. Projekte wie AutoMQ zeigen, wie durch den Aufbau einer Middleware-Schicht mit intelligenten Abstraktionen, wie Write Ahead Logs auf schnellerem Speicher und adaptive Caching- und Batch-Strategien, trotz der vermeintlichen Nachteile von Objektspeichern eine performant skalierbare Kafka-Lösung realisiert werden kann. Die Fähigkeit, eine vollständige Kafka-Kompatibilität anzubieten, ist zudem ein erheblicher Vorteil gegenüber komplett neu entwickelten Protokollen, da sie den Umstieg für Anwender erheblich erleichtert.