Modélisation de données avec Kafka? Sujets et partitions

168

Une des premières choses auxquelles je pense lorsque j'utilise un nouveau service (comme une banque de données non SGBDR ou une file d'attente de messages) est: "Comment dois-je structurer mes données?".

J'ai lu et regardé quelques documents d'introduction. En particulier, prenez, par exemple, Kafka: un système de messagerie distribuée pour le traitement des journaux , qui écrit:

  • "un sujet est le conteneur auquel les messages sont associés"
  • "la plus petite unité de parallélisme est la partition d'un sujet. Cela implique que tous les messages qui ... appartiennent à une partition particulière d'un sujet seront consommés par un consommateur dans un groupe de consommateurs."

Sachant cela, quel serait un bon exemple illustrant comment utiliser les rubriques et les partitions? Quand quelque chose devrait-il être un sujet? Quand quelque chose devrait-il être une partition?

À titre d'exemple, disons que mes données (Clojure) ressemblent à:

{: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"}

Le sujet doit-il être basé user-id? viewed? at? Et la partition?

Comment je décide?

David J.
la source
3
Étrange cela parle de sujets et de partitions, mais pas nécessairement d'évolution des données qu'ils contiennent. Que faire si vous souhaitez associer des agents utilisateurs ou des en-têtes à ces événements de "vue utilisateur"? Comment évoluez-vous et communiquez-vous cela d'une manière aux consommateurs en aval?
OneCricketeer

Réponses:

136

Lors de la structuration de vos données pour Kafka, cela dépend vraiment de la manière dont elles sont censées être utilisées.

Dans mon esprit, un sujet est un regroupement de messages d'un type similaire qui seront consommés par le même type de consommateur, donc dans l'exemple ci-dessus, je n'aurais qu'un seul sujet et si vous décidez de pousser un autre type de données via Kafka, vous pouvez ajouter un nouveau sujet pour cela plus tard.

Les sujets sont enregistrés dans ZooKeeper, ce qui signifie que vous pourriez rencontrer des problèmes si vous essayez d'en ajouter trop, par exemple le cas où vous avez un million d'utilisateurs et avez décidé de créer un sujet par utilisateur.

Les partitions, en revanche, sont un moyen de paralléliser la consommation des messages et le nombre total de partitions dans un cluster de courtiers doit être au moins le même que le nombre de consommateurs dans un groupe de consommateurs pour donner un sens à la fonction de partitionnement. Les consommateurs d'un groupe de consommateurs se partageront le fardeau du traitement du sujet entre eux en fonction du partitionnement de sorte qu'un consommateur ne sera concerné que par les messages de la partition elle-même "assignée à".

Le partitionnement peut être défini explicitement en utilisant une clé de partition du côté producteur ou s'il n'est pas fourni, une partition aléatoire sera sélectionnée pour chaque message.

Lundahl
la source
5
Ainsi, au lieu d'utiliser les rubriques comme moyen d'obtenir des données par identifiant d'utilisateur, ce qui accable Zookeeper, il est préférable de partitionner par identifiant d'utilisateur et que les consommateurs basés sur l'identifiant utilisateur s'abonnent à chaque partition si?
Ravindranath Akila
4
@RavindranathAkila 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. me fait penser que ce n'est pas le bon outil pour ce que vous avez décrit - mais plus encore, le sujet serait "Événements de vue de page"? Et toutes les pages vues seraient dans ce "sujet". Les partitions semblent plus sur le parallélisme, les répliques et tout?
The Dembinski
Merci :) Enfin, j'ai une réponse: P
Ravindranath Akila
62

Une fois que vous saurez comment partitionner votre flux d'événements, le nom du sujet sera facile, alors répondons d'abord à cette question.

@Ludd est correct - la structure de partition que vous choisissez dépendra en grande partie de la manière dont vous souhaitez traiter le flux d'événements. Idéalement, vous voulez une clé de partition, ce qui signifie que le traitement de vos événements est local à la partition .

Par exemple:

  1. Si vous vous souciez de la durée moyenne sur site des utilisateurs, vous devez partitionner par :user-id. De cette façon, tous les événements liés à l'activité du site d'un seul utilisateur seront disponibles dans la même partition. Cela signifie qu'un moteur de traitement de flux tel qu'Apache Samza peut calculer le temps moyen sur site pour un utilisateur donné simplement en regardant les événements dans une seule partition. Cela évite d'avoir à effectuer tout type de traitement global de partition coûteux
  2. Si vous vous souciez des pages les plus populaires de votre site Web, vous devez les partitionner par :viewedpage. Encore une fois, Samza sera en mesure de garder un compte des vues d'une page donnée simplement en regardant les événements dans une seule partition

En règle générale, nous essayons d'éviter de devoir nous fier à l'état global (comme le fait de garder les décomptes dans une base de données distante comme DynamoDB ou Cassandra), et à la place de pouvoir travailler en utilisant l'état local de la partition. En effet, l'état local est une primitive fondamentale dans le traitement des flux .

Si vous avez besoin des deux cas d'utilisation ci-dessus, un modèle courant avec Kafka consiste à partitionner d'abord par disons :user-id, puis à re-partitionner en étant :viewedprêt pour la phase suivante du traitement.

Sur les noms de sujets - une évidence ici serait eventsou user-events. Pour être plus précis, vous pouvez utiliser events-by-user-idet / ou events-by-viewed.

Alex Dean
la source
8
J'ai vu des références où vous publieriez les événements sur deux sujets: un par travailleur / utilisation prévue. Dans ce cas, il pourrait y avoir deux sujets, avec deux schémas de partitionnement différents.
François Beausoleil
7

Ce n'est pas exactement lié à la question, mais si vous avez déjà décidé de la ségrégation logique des enregistrements en fonction des sujets et que vous souhaitez optimiser le nombre de sujets / partitions dans Kafka, ce blog pourrait vous être utile.

Principaux points à retenir en bref:

  • En général, plus il y a de partitions dans un cluster Kafka, plus le débit peut être élevé. Soit le maximum réalisable sur une seule partition pour la production p et la consommation c . Disons que votre débit cible est t . Ensuite, vous devez avoir au moins max ( t / p , t / c ) partitions.

  • Actuellement, dans Kafka, chaque courtier ouvre un descripteur de fichier à la fois de l'index et du fichier de données de chaque segment de journal. Ainsi, plus il y a de partitions, plus il faut configurer la limite de descripteur de fichier ouvert dans le système d'exploitation sous-jacent. Par exemple, dans notre système de production, nous avons vu une fois une erreur disant too many files are open, alors que nous avions environ 3600 partitions de sujets.

  • Lorsqu'un courtier est arrêté de manière malpropre (par exemple, kill -9), l'indisponibilité observée peut être proportionnelle au nombre de partitions.

  • La latence de bout en bout dans Kafka est définie par le temps entre le moment où un message est publié par le producteur et le moment où le message est lu par le consommateur. En règle générale, si vous vous souciez de la latence, c'est probablement une bonne idée de limiter le nombre de partitions par courtier à 100 x b x r , où b est le nombre de courtiers dans un cluster Kafka et r est le facteur de réplication.

Bitswazsky
la source
4

Je pense que le nom du sujet est la conclusion d'un type de message, et le producteur publie un message sur le sujet et le message d'abonnement du consommateur via un sujet d'abonnement.

Un sujet peut avoir plusieurs partitions. la partition est bonne pour le parallélisme. la partition est aussi l'unité de réplication, donc dans Kafka, le leader et le suiveur sont également dits au niveau de la partition. En fait, une partition est une file d'attente ordonnée dont l'ordre est l'ordre d'arrivée des messages. Et le sujet est composé d'une ou plusieurs files d'attente en un mot simple. Cela nous est utile pour modéliser notre structure.

Kafka est développé par LinkedIn pour l'agrégation et la livraison de journaux. cette scène est très bonne à titre d'exemple.

Les événements de l'utilisateur sur votre site Web ou votre application peuvent être enregistrés par votre serveur Web, puis envoyés au courtier Kafka via le producteur. Dans le producteur, vous pouvez spécifier la méthode de partition, par exemple: type d'événement (un événement différent est enregistré dans une partition différente) ou heure de l'événement (partitionner un jour dans une période différente selon la logique de votre application) ou type d'utilisateur ou simplement pas de logique et équilibrer tous les journaux en plusieurs partitions.

Concernant votre cas en question, vous pouvez créer une rubrique appelée "page-view-event" et créer N partitions via des clés de hachage pour distribuer les journaux de manière uniforme dans toutes les partitions. Ou vous pouvez choisir une logique de partition pour faire la distribution des journaux par votre esprit.

GuangshengZuo
la source