Warum kann es in Apache Kafka nicht mehr Consumer-Instanzen als Partitionen geben?

73

Ich lerne etwas über Kafka und lese hier den Einführungsabschnitt

https://kafka.apache.org/documentation.html#introduction

speziell der Teil über Verbraucher. Im vorletzten Absatz der Einleitung heißt es

Kafka macht es besser. Durch den Begriff der Parallelität - der Partition - innerhalb der Themen kann Kafka sowohl Bestellgarantien als auch Lastausgleich über einen Pool von Verbraucherprozessen bereitstellen. Dies wird erreicht, indem die Partitionen im Thema den Verbrauchern in der Verbrauchergruppe zugewiesen werden, sodass jede Partition von genau einem Verbraucher in der Gruppe verwendet wird. Auf diese Weise stellen wir sicher, dass der Verbraucher der einzige Leser dieser Partition ist und die Daten in der richtigen Reihenfolge verwendet. Da es viele Partitionen gibt, wird die Last immer noch auf viele Consumer-Instanzen verteilt. Beachten Sie jedoch, dass es nicht mehr Consumer-Instanzen als Partitionen geben kann.

Meine Verwirrung ergibt sich aus diesem letzten Satz, denn im Bild rechts über dem Absatz, in dem der Autor zwei Verbrauchergruppen und ein Thema mit vier Partitionen darstellt, gibt es mehr Verbraucherinstanzen als Partitionen!

Es macht auch keinen Sinn, dass es nicht mehr Consumer-Instanzen als Partitionen geben kann, da dann Partitionen unglaublich klein wären und der Aufwand beim Erstellen einer neuen Partition für jede Consumer-Instanz Kafka zum Erliegen bringen würde. Ich verstehe, dass Partitionen zur Fehlertoleranz und zur Reduzierung der Auslastung eines Servers verwendet werden, aber der obige Satz ist im Kontext eines verteilten Systems, das Tausende von Verbrauchern gleichzeitig verarbeiten soll, nicht sinnvoll.

almel
quelle

Antworten:

73

Ok, um es zu verstehen, muss man mehrere Teile verstehen.

  1. Um die Gesamtbestellmenge für die Bestellung bereitzustellen, kann die Nachricht nur an einen Verbraucher gesendet werden. Andernfalls wäre es äußerst ineffizient, da es warten müsste, bis alle Verbraucher die Nachricht erhalten, bevor die nächste gesendet wird:

Obwohl der Server die Nachrichten der Reihe nach austeilt, werden die Nachrichten asynchron an die Verbraucher übermittelt, sodass sie bei verschiedenen Verbrauchern möglicherweise nicht in der richtigen Reihenfolge eintreffen. Dies bedeutet effektiv, dass die Reihenfolge der Nachrichten bei parallelem Verbrauch verloren geht. Messaging-Systeme umgehen dies häufig, indem sie den Begriff "exklusiver Verbraucher" verwenden, der es nur einem Prozess ermöglicht, aus einer Warteschlange zu konsumieren. Dies bedeutet jedoch natürlich, dass bei der Verarbeitung keine Parallelität besteht.

Kafka macht es besser. Durch den Begriff der Parallelität - der Partition - innerhalb der Themen kann Kafka sowohl Bestellgarantien als auch Lastausgleich über einen Pool von Verbraucherprozessen bereitstellen. Dies wird erreicht, indem die Partitionen im Thema den Verbrauchern in der Verbrauchergruppe zugewiesen werden, sodass jede Partition von genau einem Verbraucher in der Gruppe verwendet wird. Auf diese Weise stellen wir sicher, dass der Verbraucher der einzige Leser dieser Partition ist und die Daten in der richtigen Reihenfolge verwendet. Da es viele Partitionen gibt, wird die Last immer noch auf viele Consumer-Instanzen verteilt. Beachten Sie jedoch, dass es nicht mehr Consumer-Instanzen als Partitionen geben kann.

Kafka bietet nur eine Gesamtreihenfolge über Nachrichten innerhalb einer Partition, nicht zwischen verschiedenen Partitionen in einem Thema.

Was Sie auch für eine Leistungsstrafe halten (mehrere Partitionen), ist tatsächlich ein Leistungsgewinn, da Kafka Aktionen verschiedener Partitionen vollständig parallel ausführen kann, während er darauf wartet, dass andere Partitionen beendet werden.

  1. Das Bild zeigt verschiedene Verbrauchergruppen, aber die Beschränkung auf maximal einen Verbraucher pro Partition liegt nur innerhalb einer Gruppe. Sie können immer noch mehrere Verbrauchergruppen haben.

Zu Beginn werden die beiden Szenarien beschrieben:

Wenn alle Consumer-Instanzen dieselbe Consumer-Gruppe haben, funktioniert dies genau wie ein herkömmlicher Warteschlangenausgleich über die Consumer.

Wenn alle Consumer-Instanzen unterschiedliche Consumer-Gruppen haben, funktioniert dies wie Publish-Subscribe, und alle Nachrichten werden an alle Consumer gesendet.

Je mehr Abonnentengruppen Sie haben, desto geringer ist die Leistung, da kafka die Nachrichten an alle diese Gruppen replizieren und die Gesamtbestellung garantieren muss.

Je weniger Gruppen und mehr Partitionen Sie haben, desto mehr profitieren Sie von der Parallelisierung der Nachrichtenverarbeitung.

Peter
quelle
30
Die Frage kann also mit folgender Klarstellung beantwortet werden: Es kann nicht mehr Consumer-Instanzen innerhalb einer einzelnen Consumer-Gruppe geben als Partitionen.
Almel
@peter "obwohl der Server die Nachrichten in der richtigen Reihenfolge verteilt": Wie gibt der Kafka-Server die Nachrichten an die Verbraucher weiter? Ich dachte, da der Offset vom Verbraucher beibehalten wird, zieht der Verbraucher die Nachrichten aus dem Kafka-Thema. Oder ist es so, als würde der Verbraucher kafka mitteilen, bis er gelesen hat, und kafka Daten an den Verbraucher weiterleiten. Meine eigentliche Frage ist, ob Kafka Push basiert. oder ziehen basiert?
Vishnu Viswanath
@ Peter Schöne Antwort, aber es gibt eine wichtige Sache, die nicht angesprochen wird. Was ist, wenn wir genau eine Partition pro Verbraucher wollen? Das würde bedeuten, dass innerhalb einer Gruppe die gleiche Anzahl von Partitionen und Verbrauchern vorhanden ist (wenn Kafka den richtigen Ausgleich durchführt und dies auch tut). OK, jetzt möchten wir außerdem sicherstellen, dass wir auch dann eine Partition pro Verbraucherinstanz haben, wenn einige Consumer-Instanzen ausfallen. Ein logischer Weg, dies zu tun, wäre, der Gruppe mehr Verbraucher hinzuzufügen. Während alles in Ordnung ist, würden sie nichts tun, aber wenn ein Verbraucher ausfällt, würde einer von ihnen diese Partition erhalten. Warum ist dies nicht erlaubt?
Miljen Mikic
@peter "Je mehr Abonnentengruppen Sie haben, desto geringer ist die Leistung, da kafka die Nachrichten an alle diese Gruppen replizieren und die Gesamtbestellung garantieren muss." Ist die Latenz in diesem Fall linear oder sublinear in Bezug auf die Anzahl der Verbrauchergruppen?
Novemberland
1
@Miljen Mikic So wie es ist, werden die mehreren Verbraucher als redundant gehalten und im Falle eines Ausfalls des primären Verbrauchers werden andere Verbraucher zufällig der entsprechenden Partition zugewiesen.
Prashant
6

Es ist wichtig daran zu erinnern, dass Kafka einen Offset pro [Verbrauchergruppe, Thema, Partition] behält. Das ist der Grund.

Ich denke der Satz

Beachten Sie jedoch, dass es nicht mehr Consumer-Instanzen als Partitionen geben kann.

bezieht sich auf den Modus "Automatische Neuausrichtung von Verbrauchergruppen", den Standardverbrauchermodus, wenn Sie nur eine bestimmte Anzahl von Verbrauchern für eine Liste von Themen abonnieren ().

Ich gehe davon aus, dass zumindest mit Kafka 0.9.x nichts verhindert, dass mehrere Consumer-Instanzen, Mitglieder derselben Gruppe, von derselben Partition lesen.

Sie können so etwas in zwei oder mehr verschiedenen Threads tun

Properties props = new Properties();
props.put(ConsumerConfig.GROUP_ID_CONFIG, "MyConsumerGroup");
props.put("enable.auto.commit", "false");
consumer = new KafkaConsumer<>(props);
TopicPartition partition0 = new TopicPartition("mytopic", 0);
consumer.assign(Arrays.asList(partition0));
ConsumerRecords<Integer, String> records = consumer.poll(1000);

und Sie werden zwei (oder mehr) Verbraucher haben, die von derselben Partition lesen.

Das "Problem" ist nun, dass beide Verbraucher denselben Offset teilen. Sie haben keine andere Option, da nur eine Gruppe, ein Thema und eine Partition im Spiel sind.

Wenn beide Verbraucher gleichzeitig den aktuellen Offset lesen, lesen beide den gleichen Wert und beide erhalten die gleichen Nachrichten.

Wenn Sie möchten, dass jeder Verbraucher unterschiedliche Nachrichten liest, müssen Sie diese synchronisieren, damit jeweils nur einer den Offset abrufen und festschreiben kann.

Luciano Afranllie
quelle
3

Es gibt einen Grund, warum Kafka nicht mehrere Consumer pro Partition unterstützen kann.

Kafka Broker schreibt Daten pro Partition in die Datei. Angenommen, wenn zwei Partitionen konfiguriert sind, erstellt der Broker zwei Dateien und weist mehrere Verbrauchergruppen zu, in denen Nachrichten gesendet werden können.

Jetzt verbraucht für jede Partition nur ein Verbraucher Nachrichten basierend auf dem Versatz der Datei. Beispiel: Verbraucher 1 liest zuerst Nachrichten vom Datei-Offset 0 bis 4096. Jetzt sind diese Offsets Teil der Nutzlast, sodass Verbraucher wissen, welcher Offset verwendet werden soll, wenn sie nach den nächsten gelesenen Nachrichten fragen.

Wenn mehrere Verbraucher von derselben Partition lesen, liest Verbraucher 1 aus einer Datei mit dem Versatz 0-4096, aber Verbraucher 2 versucht weiterhin, vom Versatz 0 zu lesen, es sei denn, er empfängt auch eine an Verbraucher 1 gesendete Nachricht. Wenn nun dieselben Nachrichten an mehrere Verbraucher gesendet werden als Da es sich nicht um einen Lastausgleich handelt, hat Kafka sie in Verbrauchergruppen unterteilt, damit alle Verbrauchergruppen Nachrichten empfangen können. Innerhalb der Verbrauchergruppe kann jedoch nur ein Verbraucher Nachrichten empfangen.

rjoshi
quelle
1
Sie sagen, Kafka kann nicht mehrere Konsumenten pro Partition haben. Wenn C1 und C2 aus verschiedenen Verbrauchergruppen stammen, können sie dann von derselben Partition lesen? Ich denke, sie müssen dazu in der Lage sein, sonst verwendet Kafka effektiv einen exklusiven Consumer-Ansatz (exklusiv für eine bestimmte Partition), und Sie erhalten keinen Lastausgleich. Es wäre sehr hilfreich, von Ihnen zu hören, was Kafka tatsächlich tut, um zwischen Verbrauchern aus verschiedenen Verbrauchergruppen zu unterscheiden. Da Kafka Daten auf die Festplatte schreibt, scheint es sehr langsam zu sein, mehrere Konsumenten aus verschiedenen Gruppen zu haben, wenn die Schreibvorgänge nicht mehr linear sind.
Almel
2

In Kafka kann nur eine Consumer-Instanz Nachrichten von einer Partition verarbeiten. Wenn Consumer-Instanzen mehr als Partitionen sind, werden keine zusätzlichen Consumer-Instanzen verwendet. Kafka erlaubt diese zusätzlichen Consumer-Instanzen also nicht.

Wenn nun mehrere Verbraucher Partitionen verbrauchen können, gibt es keine Reihenfolge beim Verbrauch von Nachrichten. Dies ist der Grund, warum kafka nicht mehrere Konsumenten pro Partition zulässt

Abhinav
quelle
2

Das Kafka-Verbrauchergruppenmodell ist eine Mischung aus Warteschlangenmechanismus, bei dem die von einer Verbraucherinstanz einmal gelesene Nachricht sofort aus der Warteschlange gelöscht wird, und Pub / Sub-Mechanismus, bei dem die Nachricht erst gelöscht wird, wenn die Aufbewahrungsfrist festgelegt wurde oder bis sie abläuft und für verfügbar ist alle Verbraucherinstanzen bis zum Ablauf. Wenn Sie also einen Anwendungsfall haben, in dem Sie ein Pub / Sub-Modell verwenden möchten, es aber als Warteschlangenmechanismus nutzen möchten, erstellen Sie eine Verbrauchergruppe für alle Ihre Verbraucherinstanzen. Da Kafka Partitionen auf die Consumer-Instanzen innerhalb einer einzelnen Consumer-Gruppe verteilt, wird garantiert, dass 1 Nachricht nur einmal verarbeitet wird. Wenn Kafka es Ihnen ermöglicht, mehr Consumer-Instanzen innerhalb einer einzelnen Consumer-Gruppe zu haben, übertrifft dies den Zweck der Consumer-Gruppe.

Betrachten Sie dieses Beispiel:

Die REST-API pub1 hat 4 Nachrichten zu Thema1 veröffentlicht, die 4 Partitionen Teil1 bis Teil4 haben, sodass jeder Teil 1 Nachricht hat.

Sie haben 2 Microservices sub1 und sub2 als Abonnenten und es werden 4 Instanzen jedes Microservices ausgeführt.

Wenn Sie nun 2 Verbrauchergruppen erstellen, wird eine für jede miroservice-Subinstanz1 Teil1, Unterinstanz2 Teil2 usw. zugeordnet. In ähnlicher Weise wird Unterinstanz1 Teil1, Unterinstanz2 Teil2 usw. zugeordnet.

Solange Ihre Consumer-Instanzen innerhalb jeder Consumer-Gruppe kleiner oder gleich der Anzahl der Partitionen sind, wird jede Instanz Ihres Microservice die Nachricht nur einmal verarbeiten. In diesem Fall verarbeiten sub1instance1 und sub2instance msg1 von part1.

Wenn es mehr Consumer-Instanzen als Partitionen gibt, muss Kafka mehreren Consumer-Instanzen dieselben Partitionen zuweisen, damit Nachrichten von jeder Consumer-Instanz, die dieser Partition zugeordnet ist, mehrmals verarbeitet werden. Dies ist der Grund, warum Kafka verhindert, dass wir mehr Consumer-Instanzen innerhalb einer Consumer-Gruppe haben als die Anzahl der Partitionen innerhalb eines Themas, das die Consumer-Gruppe abonniert hat.

Hoffe das macht Sinn.

Kaycee
quelle
Es macht wirklich Sinn. Ich frage mich, warum diese Antwort nicht genug positive Stimmen hat.
Tushar
0

Nun, eine Verbrauchergruppe kann so viele Instanzen haben, wie für ein bestimmtes Thema erforderlich sind. Die zusätzlichen Instanzen sind jedoch für dieses Thema inaktiv. Hier meine ich mit zusätzlichen Instanzen Instanzen> nein. von Partitionen in einem Thema, das es abonniert hat.

Umgekehrt denken wir, dass dieselbe Verbrauchergruppe mehr als ein Thema abonnieren kann, oder? Was ist, wenn jedes Thema, das es abonniert hat, eine andere Nummer hat? von Partitionen ist es möglich, oder?

Daher können Sie {Nr. von Instanzen == nein. of partitions} Theorie über die Verbrauchergruppe basierend auf einem der abonnierten Themen nur richtig?

Praktisch gesehen möchten Sie also zumindest keine haben. von Instanzen gleich Nr. der Partition für ein bestimmtes Thema, aber wenn Sie mehr haben, gibt es keinen Schaden, da für dieses Thema die zusätzlichen Instanzen inaktiv bleiben.

Beispiel:

  • Thema A mit 2 Partitionen
  • Thema B mit 3 Partitionen
  • Verbrauchergruppe mit 3 Instanzen

     A[1 2]   B[1 2 3]
    
         [x y z] (consumer group)
    

Für das Thema 'B' sind jetzt alle 3 Consumer-Instanzen aktiv (Lesen von jeweils 1 Partition). Für das Thema 'A' sind jedoch nur 2 von 3 Consumer-Instanzen aktiv (dh 1 von ihnen ist als Thema inaktiv hat nur 2 Partitionen).

sactiw
quelle
@anonymous Bitte begründen Sie (-1), damit ich (alle) Ihr Anliegen mit der gegebenen Antwort / Erklärung verstehen kann.
2.