Apache Kafka ist eine leistungsstarke und hoch skalierbare Event-Streaming-Plattform. Um das volle Potenzial von Kafka auszuschöpfen, ist es erforderlich, das Design Ihrer Anwendung sorgfältig zu planen. Es kann leicht vorkommen, dass Kafka-Anwendungen entwickelt werden, die eine unzureichende Leistung aufweisen oder letztendlich an ihre Skalierbarkeitsgrenzen stoßen. Seit 2015 bietet IBM den IBM Event Streams-Service an, einen vollständig verwalteten Apache Kafka-Service, der auf IBM Cloud ausgeführt wird. Seitdem hat der Service vielen Kunden sowie Teams innerhalb von IBM dabei geholfen, Skalierbarkeits- und Leistungsprobleme mit den von ihnen geschriebenen Kafka-Anwendungen zu lösen.
Dieser Artikel beschreibt einige der häufigsten Probleme von Apache Kafka und enthält Empfehlungen, wie Sie Skalierbarkeitsprobleme bei Ihren Anwendungen vermeiden können.
Bestimmte Kafka-Operationen funktionieren so, dass der Client Daten an den Broker sendet und auf eine Antwort wartet. Ein kompletter Roundtrip kann 10 Millisekunden dauern. Das klingt zwar schnell, beschränkt Sie jedoch auf maximal 100 Operationen pro Sekunde. Daher wird empfohlen, solche Operationen nach Möglichkeit zu vermeiden. Glücklicherweise bieten Kafka-Clients Möglichkeiten, diese Roundtrip-Zeiten zu umgehen. Sie müssen lediglich sicherstellen, dass Sie diese Vorteile nutzen.
Tipps zur Maximierung des Durchsatzes:
Wenn Sie das oben Genannte gelesen haben und sich gefragt haben: „Oh je, wird das meine Anwendung nicht komplexer machen?“, lautet die Antwort: Ja, das wird es wahrscheinlich. Es besteht ein Kompromiss zwischen Durchsatz und Komplexität der Anwendung. Was die Netzwerk-Roundtrip-Zeit zu einer besonders heimtückischen Herausforderung macht, ist die Tatsache, dass nach Erreichen dieser Grenze umfangreiche Anwendungsänderungen erforderlich sein können, um weitere Durchsatzverbesserungen zu erzielen.
Eine nützliche Funktion von Kafka ist, dass es die „Lebendigkeit” der konsumierenden Anwendungen überwacht und alle Anwendungen trennt, die möglicherweise ausgefallen sind. Das funktioniert, indem der Broker verfolgt, wann jeder konsumierende Client zuletzt „poll“ aufgerufen hat (Kafkas Begriff für die Anforderung weiterer Nachrichten). Wenn ein Client nicht häufig genug abfragt, geht der Broker, mit dem er verbunden ist, davon aus, dass ein Fehler aufgetreten ist, und trennt die Verbindung. Auf diese Weise können Clients, bei denen keine Probleme auftreten, einspringen und die Arbeit des ausgefallenen Clients übernehmen.
Leider kann der Kafka-Broker bei diesem Schema nicht zwischen einem Client, der für die Verarbeitung der empfangenen Nachrichten viel Zeit benötigt, und einem Client, der tatsächlich ausgefallen ist, unterscheiden. Stellen Sie sich eine konsumierende Anwendung vor, die in einer Schleife 1) einen Abfrage aufruft und einen Stapel von Nachrichten zurückerhält oder 2) jede Nachricht im Stapel verarbeitet, wobei die Verarbeitung jeder Nachricht 1 Sekunde dauert.
Wenn dieser Verbraucher Pakete von 10 Nachrichten empfängt, dann beträgt der Abstand zwischen den Abfrageaufrufen ungefähr 10 Sekunden. Standardmäßig erlaubt Kafka eine Zeitspanne von bis zu 300 Sekunden (5 Minuten) zwischen den Abfragen, bevor die Verbindung zum Client getrennt wird, sodass in diesem Szenario alles reibungslos funktionieren würde. Aber was passiert an einem besonders arbeitsreichen Tag, wenn sich Nachrichten zu dem Thema, das die Anwendung verarbeitet, ansammeln? Anstatt nur 10 Nachrichten von jedem Poll-Aufruf zurückzuerhalten, erhält Ihre Anwendung 500 Nachrichten (dies ist standardmäßig die maximale Anzahl von Datensätzen, die durch einen Poll-Aufruf zurückgegeben werden können). Das würde zu einer ausreichenden Verarbeitungszeit für Kafka führen, um zu entscheiden, dass die Anwendungsinstanz ausgefallen ist, und die Verbindung zu trennen. Das sind schlechte Nachrichten.
Es wird Sie freuen zu erfahren, dass es noch schlimmer kommen kann. Es ist möglich, dass eine Art Rückkopplungsschleife entsteht. Da Kafka beginnt, Clients zu trennen, weil sie nicht häufig genug abfragen, gibt es weniger Instanzen der Anwendung, die Nachrichten verarbeiten können. Die Wahrscheinlichkeit, dass es zu einem erheblichen Rückstau an Nachrichten zu diesem Thema kommt, steigt. Dadurch steigt auch die Wahrscheinlichkeit, dass mehr Kunden große Mengen an Nachrichten erhalten und zu lange benötigen, um diese zu verarbeiten. Schließlich geraten alle Instanzen der konsumierenden Anwendung in eine Neustartschleife, und es wird keine nützliche Arbeit mehr verrichtet.
Welche Maßnahmen können Sie dagegen ergreifen?
Wir werden später in diesem Artikel auf das Thema Verbraucherausfälle zurückkommen, wenn wir uns damit befassen, wie sie eine Neugewichtung der Verbrauchergruppen auslösen können und welche disruptiven Auswirkungen dies haben kann.
Unter der Oberfläche funktioniert das vom Kafka-Consumer zum Empfangen von Nachrichten verwendete Protokoll, indem es eine „Fetch“-Anfrage an einen Kafka-Broker sendet. Als Teil dieser Anfrage gibt der Client an, was der Broker tun soll, wenn keine Nachrichten zurückgegeben werden können, einschließlich der Wartezeit, bevor der Broker eine leere Antwort sendet. Standardmäßig weisen Kafka-Konsumenten die Broker an, bis zu 500 Millisekunden (gesteuert durch die Konsumentenkonfiguration „fetch.max.wait.ms“) zu warten, bis mindestens 1 Byte an Nachrichtendaten verfügbar ist (gesteuert durch die Konfiguration „fetch.min.bytes“).
Eine Wartezeit von 500 Millisekunden erscheint zunächst nicht unangemessen. Wenn Ihre Anwendung jedoch Nutzer hat, die größtenteils inaktiv sind, und auf beispielsweise 5.000 Instanzen skaliert wird, bedeutet dies potenziell 2.500 Anfragen pro Sekunde, die keine Aktion ausführen. Jede dieser Anfragen beansprucht CPU-Zeit auf dem Broker für die Verarbeitung und kann im Extremfall die Leistung und Stabilität der Kafka-Clients beeinträchtigen, die nützliche Aufgaben ausführen sollen.
In der Regel besteht Kafkas Ansatz zur Skalierung darin, weitere Broker hinzuzufügen und anschließend die Topic-Partitionen gleichmäßig auf alle Broker, sowohl alte als auch neue, neu zu verteilen. Leider ist dieser Ansatz möglicherweise nicht zielführend, wenn Ihre Clients Kafka mit unnötigen Abrufanfragen überlasten. Jeder Client sendet Abrufanfragen an jeden Broker, der eine Themenpartition verursacht, aus der der Client Nachrichten abruft. Daher ist es möglich, dass selbst nach der Skalierung des Kafka-Clusters und der Neuverteilung der Partitionen die meisten Ihrer Clients weiterhin Abrufanfragen an die meisten Broker senden.
Also, was können Sie tun?
Wenn Sie bereits Erfahrung mit anderen Publish-Subscribe-Systemen haben (z. B. Message Queuing Telemetry Transport, kurz MQTT), könnten Sie erwarten, dass Kafka-Themen sehr leichtgewichtig und nahezu kurzlebig sind. Das ist jedoch nicht der Fall. Kafka ist mit einer Vielzahl von Themen, die in Tausenden gemessen werden, wesentlich besser vertraut. Es wird auch erwartet, dass Kafka-Themen relativ langlebig sind. Praktiken wie das Erstellen eines Themas, um eine einzelne Antwortnachricht zu empfangen, und das anschließende Löschen des Themas sind bei Kafka unüblich und spielen die Stärken von Kafka nicht aus.
Planen Sie stattdessen Themen mit einer langen Lebensdauer. Möglicherweise teilen sie sich die Lebensdauer einer Anwendung oder einer Aktivität. Versuchen Sie auch, die Anzahl der Themen auf Hunderte oder vielleicht wenige Tausend zu begrenzen. Dies erfordert möglicherweise eine andere Sichtweise darauf, welche Nachrichten zu einem bestimmten Thema verschachtelt sind.
Eine häufig gestellte Frage lautet: „Wie viele Partitionen sollte mein Thema haben?“ Traditionell wird empfohlen, die Anzahl eher hoch anzusetzen, da das Hinzufügen von Partitionen nach der Erstellung eines Themas die Partitionierung der vorhandenen Daten in diesem Thema nicht verändert (und somit Auswirkungen auf Verbraucher haben kann, die auf die Partitionierung angewiesen sind, um die Reihenfolge der Nachrichten innerhalb einer Partition zu gewährleisten). Dies ist ein guter Ratschlag. Dennoch möchten wir einige zusätzliche Überlegungen vorschlagen:
Die meisten Kafka-Anwendungen, die Nachrichten verarbeiten, nutzen die Funktionen der Kafka-Verbrauchergruppen, um zu koordinieren, welche Clients welche Themenpartitionen verarbeiten. Sollten Ihre Erinnerungen an Verbrauchergruppen etwas unklar sein, finden Sie hier eine kurze Zusammenfassung der wichtigsten Punkte:
Mit der Entwicklung von Kafka wurden (und werden weiterhin) immer ausgefeiltere Algorithmen zur Neugewichtung entwickelt. In früheren Versionen von Kafka mussten bei einer Neugewichtung einer Verbrauchergruppe alle Clients in der Gruppe den Verbrauch einstellen, die Themenpartitionen wurden unter den neuen Mitgliedern der Gruppe neu verteilt und alle Clients nahmen den Verbrauch wieder auf. Dieser Ansatz hat zwei Nachteile (keine Sorge, diese wurden inzwischen verbessert):
Neuere Rebalancing-Algorithmen haben erhebliche Verbesserungen erzielt, indem sie, um Kafkas Terminologie zu verwenden, „Stickiness“ und „Cooperation“ hinzugefügt haben:
Trotz dieser Verbesserungen an neueren Rebalancing-Algorithmen werden Sie, wenn Ihre Anwendungen häufig von Rebalancing-Vorgängen der Verbrauchergruppe betroffen sind, weiterhin Auswirkungen auf den gesamten Messaging-Durchsatz feststellen und Netzwerkbandbreite verschwenden, da Clients gepufferte Nachrichtendaten verwerfen und erneut abrufen. Hier sind einige Lösungsvorschläge:
Branchen-Newsletter
Bleiben Sie mit dem Think-Newsletter über die wichtigsten – und faszinierendsten – Branchentrends in den Bereichen KI, Automatisierung, Daten und mehr auf dem Laufenden. Weitere Informationen finden Sie in der IBM Datenschutzerklärung.
Ihr Abonnement wird auf Englisch geliefert. In jedem Newsletter finden Sie einen Abmeldelink. Hier können Sie Ihre Abonnements verwalten oder sich abmelden. Weitere Informationen finden Sie in unserer IBM Datenschutzerklärung.
Sie sind nun ein Experte für die Skalierung von Kafka-Anwendungen. Wir laden Sie ein, diese Punkte in die Praxis umzusetzen und das vollständig verwaltete Kafka-Angebot auf IBM Cloud zu testen. Bei Schwierigkeiten bei der Einrichtung konsultieren Sie bitte den Leitfaden zum Einstieg und die FAQs.
IBM® Event Streams ist eine Event-Streaming-Software, die auf der Open-Source-Software Apache Kafka basiert. Es ist als vollständig verwalteter Service in der IBM® Cloud oder zum Selbsthosten verfügbar.
Erschließen Sie Ihr Geschäftspotenzial mit IBM Integrationslösungen, die Anwendungen und Systeme für den schnellen und sicheren Zugriff auf wichtige Daten verbinden.
Schalten Sie neue Funktionen frei und steigern Sie die geschäftliche Agilität mit IBM Cloud Consulting Services.