Datenmodellierung mit Kafka? Themen und Partitionen

168

Eines der ersten Dinge, an die ich denke, wenn ich einen neuen Dienst verwende (z. B. einen Nicht-RDBMS-Datenspeicher oder eine Nachrichtenwarteschlange), ist: "Wie soll ich meine Daten strukturieren?".

Ich habe einige Einführungsmaterialien gelesen und gesehen. Nehmen wir zum Beispiel Kafka: ein verteiltes Nachrichtensystem für die Protokollverarbeitung , das schreibt:

  • "Ein Thema ist der Container, dem Nachrichten zugeordnet sind."
  • "Die kleinste Einheit der Parallelität ist die Partition eines Themas. Dies bedeutet, dass alle Nachrichten, die ... zu einer bestimmten Partition eines Themas gehören, von einem Verbraucher in einer Verbrauchergruppe konsumiert werden."

Wenn Sie dies wissen, was wäre ein gutes Beispiel für die Verwendung von Themen und Partitionen? Wann sollte etwas ein Thema sein? Wann sollte etwas eine Partition sein?

Nehmen wir als Beispiel an, meine (Clojure-) Daten sehen folgendermaßen aus:

{:user-id 101 :viewed "/page1.html" :at #inst "2013-04-12T23:20:50.22Z"}
{:user-id 102 :viewed "/page2.html" :at #inst "2013-04-12T23:20:55.50Z"}

Sollte das Thema darauf basieren user-id? viewed? at? Was ist mit der Partition?

Wie entscheide ich mich?

David J.
quelle
3
Seltsamerweise handelt es sich dabei um Themen und Partitionen, aber nicht unbedingt um die Entwicklung der darin enthaltenen Daten. Was ist, wenn Sie Benutzeragenten oder Header an diese "Benutzeransicht" -Ereignisse anhängen möchten? Wie entwickeln Sie das weiter und kommunizieren es den nachgeschalteten Verbrauchern?
OneCricketeer

Antworten:

136

Bei der Strukturierung Ihrer Daten für Kafka kommt es wirklich darauf an, wie sie konsumiert werden sollen.

In meinen Augen ist ein Thema eine Gruppierung von Nachrichten eines ähnlichen Typs, die von demselben Verbrauchertyp konsumiert werden. Im obigen Beispiel hätte ich nur ein einziges Thema, und wenn Sie sich entscheiden, eine andere Art von Nachrichten zu pushen Daten über Kafka können Sie später ein neues Thema hinzufügen.

Themen werden in ZooKeeper registriert. Dies bedeutet, dass Sie möglicherweise auf Probleme stoßen, wenn Sie versuchen, zu viele davon hinzuzufügen, z. B. wenn Sie eine Million Benutzer haben und beschlossen haben, ein Thema pro Benutzer zu erstellen.

Partitionen hingegen sind eine Möglichkeit, den Verbrauch der Nachrichten zu parallelisieren, und die Gesamtzahl der Partitionen in einem Brokercluster muss mindestens der Anzahl der Verbraucher in einer Verbrauchergruppe entsprechen, um die Partitionierungsfunktion zu verstehen. Verbraucher in einer Verbrauchergruppe teilen die Last der Verarbeitung des Themas entsprechend der Partitionierung unter sich auf, sodass sich ein Verbraucher nur mit Nachrichten befasst, denen die Partition selbst "zugewiesen" ist.

Die Partitionierung kann entweder explizit mithilfe eines Partitionsschlüssels auf der Herstellerseite festgelegt werden, oder wenn nicht angegeben, wird für jede Nachricht eine zufällige Partition ausgewählt.

Lundahl
quelle
5
Anstatt die Themen als Methode zum Abrufen von Daten pro Benutzer-ID zu verwenden, wodurch Zookeeper überfordert wird, ist es besser, nach Benutzer-ID zu partitionieren und Benutzer-ID-basierte Verbraucher jede Partition abonnieren zu lassen, wenn?
Ravindranath Akila
4
@RavindranathAkila Lässt Kafka is designed to have of the order of few thousands of partitions roughly less than 10,000. And the main bottleneck is zookeeper. A better way to design such a system is to have fewer partitions and use keyed messages to distribute the data over a fixed set of partitions. mich denken, dass es nicht das richtige Werkzeug für das ist, was Sie beschrieben haben - aber mehr noch, das Thema wäre "Page View Events"? Und alle Seitenaufrufe wären in diesem "Thema". Partitionen scheinen mehr über Parallelität und Repliken und so?
Der Dembinski
Danke :) Endlich habe ich eine Antwort: P
Ravindranath Akila
62

Sobald Sie wissen, wie Sie Ihren Ereignisstrom partitionieren, ist der Themenname einfach. Beantworten wir diese Frage zuerst.

@Ludd ist korrekt - die Partitionsstruktur, die Sie auswählen, hängt weitgehend davon ab, wie Sie den Ereignisstrom verarbeiten möchten. Idealerweise möchten Sie einen Partitionsschlüssel, was bedeutet, dass Ihre Ereignisverarbeitung partitionellokal ist .

Beispielsweise:

  1. Wenn Sie sich für die durchschnittliche Zeit vor Ort der Benutzer interessieren, sollten Sie nach partitionieren :user-id. Auf diese Weise sind alle Ereignisse, die sich auf die Site-Aktivität eines einzelnen Benutzers beziehen, in derselben Partition verfügbar. Dies bedeutet, dass eine Stream-Verarbeitungs-Engine wie Apache Samza die durchschnittliche Zeit vor Ort für einen bestimmten Benutzer berechnen kann, indem nur die Ereignisse in einer einzelnen Partition betrachtet werden. Dies vermeidet, dass irgendeine Art von kostspieliger partition-globaler Verarbeitung durchgeführt werden muss
  2. Wenn Sie sich für die beliebtesten Seiten Ihrer Website interessieren, sollten Sie nach Seiten partitionieren :viewed. Auch hier kann Samza die Aufrufe einer bestimmten Seite zählen, indem er nur die Ereignisse in einer einzelnen Partition betrachtet

Im Allgemeinen versuchen wir zu vermeiden, dass wir uns auf den globalen Status verlassen müssen (z. B. die Zählung in einer entfernten Datenbank wie DynamoDB oder Cassandra) und stattdessen mit dem partition-lokalen Status arbeiten können. Dies liegt daran, dass der lokale Zustand ein grundlegendes Grundelement bei der Stream-Verarbeitung ist .

Wenn Sie beide oben genannten Anwendungsfälle benötigen, besteht ein gängiges Muster bei Kafka darin, zuerst beispielsweise zu partitionieren :user-idund dann erneut zu partitionieren von :viewedbereit für die nächste Phase der Verarbeitung.

Zu Themennamen - ein offensichtlicher hier wäre eventsoder user-events. Genauer gesagt könnten Sie mit events-by-user-idund / oder gehen events-by-viewed.

Alex Dean
quelle
8
Ich habe Referenzen gesehen, in denen Sie die Ereignisse zu zwei Themen veröffentlichen würden: eines pro Mitarbeiter / Verwendungszweck. In diesem Fall kann es zwei Themen mit zwei unterschiedlichen Partitionierungsschemata geben.
François Beausoleil
7

Dies hängt nicht genau mit der Frage zusammen. Falls Sie sich jedoch bereits für die logische Trennung von Datensätzen nach Themen entschieden haben und die Anzahl der Themen / Partitionen in Kafka optimieren möchten, ist dieser Blog möglicherweise hilfreich.

Wichtige Imbissbuden auf den Punkt gebracht:

  • Im Allgemeinen ist der Durchsatz umso höher, je mehr Partitionen sich in einem Kafka-Cluster befinden. Das auf einer einzelnen Partition für die Produktion erreichbare Maximum sei p und der Verbrauch c . Angenommen, Ihr Zieldurchsatz ist t . Dann müssen Sie mindestens max ( t / p , t / c ) Partitionen haben.

  • Derzeit öffnet in Kafka jeder Broker ein Dateihandle sowohl des Index als auch der Datendatei jedes Protokollsegments. Je mehr Partitionen vorhanden sind, desto höher muss das Limit für offene Dateihandles im zugrunde liegenden Betriebssystem konfiguriert werden. Zum Beispiel haben wir in unserem Produktionssystem einmal einen Fehler gesehen too many files are open, während wir ungefähr 3600 Themenpartitionen hatten.

  • Wenn ein Broker unrein heruntergefahren wird (z. B. kill -9), kann die beobachtete Nichtverfügbarkeit proportional zur Anzahl der Partitionen sein.

  • Die End-to-End-Latenz in Kafka wird durch den Zeitpunkt definiert, zu dem eine Nachricht vom Hersteller veröffentlicht wird und bis die Nachricht vom Verbraucher gelesen wird. Als Faustregel gilt: Wenn Sie sich für die Latenz interessieren, ist es wahrscheinlich eine gute Idee, die Anzahl der Partitionen pro Broker auf 100 x b x r zu beschränken , wobei b die Anzahl der Broker in einem Kafka-Cluster und r der Replikationsfaktor ist.

Bitswazsky
quelle
4

Ich denke, der Themenname ist eine Schlussfolgerung aus einer Art von Nachrichten, und der Produzent veröffentlicht eine Nachricht zum Thema, und der Verbraucher abonniert eine Nachricht über ein Abonnementthema.

Ein Thema kann viele Partitionen haben. Partition ist gut für Parallelität. Partition ist auch die Replikationseinheit, daher wird in Kafka Leader und Follower auch auf Partitionsebene angegeben. Tatsächlich ist eine Partition eine geordnete Warteschlange, deren Reihenfolge die Reihenfolge der eingegangenen Nachricht ist. Und das Thema besteht aus einer oder mehreren Warteschlangen in einem einfachen Wort. Dies ist nützlich, um unsere Struktur zu modellieren.

Kafka wurde von LinkedIn für die Protokollaggregation und -zustellung entwickelt. Diese Szene ist als Beispiel sehr gut.

Die Ereignisse des Benutzers in Ihrem Web oder Ihrer App können von Ihrem Web-Server protokolliert und dann über den Hersteller an den Kafka-Broker gesendet werden. In Producer können Sie die Partitionsmethode angeben, z. B.: Ereignistyp (unterschiedliches Ereignis wird in unterschiedlicher Partition gespeichert) oder Ereigniszeit (Partitionierung eines Tages in einen anderen Zeitraum gemäß Ihrer App-Logik) oder Benutzertyp oder einfach keine Logik und alle Protokolle ausgleichen in viele Partitionen.

Zu Ihrem fraglichen Fall können Sie ein Thema mit dem Namen "Seitenaufruf-Ereignis" erstellen und N Partitionen über Hash-Schlüssel erstellen, um die Protokolle gleichmäßig auf alle Partitionen zu verteilen. Oder Sie können eine Partitionslogik auswählen, um die Protokollverteilung nach Ihrem Geist durchzuführen.

GuangshengZuo
quelle