web-dev-qa-db-fra.com

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

L'une des premières choses à laquelle je pense lors de l'utilisation d'un nouveau service (tel qu'un magasin de données non-SGBDR ou une file d'attente de messages) est: "Comment structurer mes données?".

J'ai lu et regardé des documents d'introduction. En particulier, prenons, 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 d'un groupe de consommateurs."

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

Par exemple, supposons 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é sur user-id? viewed? at? Qu'en est-il de la partition?

Comment je décide?

156
David J.

Lors de la structuration de vos données pour Kafka), cela dépend vraiment de la manière dont elles sont consommées.

Dans mon esprit, un sujet est un groupe de messages d'un type similaire qui sera consommé par le même type de consommateur. Dans l'exemple ci-dessus, je n'aurais qu'un seul sujet et si vous décidiez de pousser un autre type de message données via Kafka, vous pouvez ajouter un nouveau sujet plus tard.

Les rubriques sont enregistrées 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.

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

Le partitionnement peut être explicitement défini à l'aide d'une clé de partition côté producteur ou, si elle n'est pas fournie, une partition aléatoire sera sélectionnée pour chaque message.

128
Lundahl

Une fois que vous saurez partitionner votre flux d’événements, le nom de la rubrique sera facile. Répondons d’abord à cette question.

@Ludd est correct - la structure de partition que vous choisirez dépendra en grande partie de la façon dont vous souhaitez traiter le flux d'événements. Idéalement, vous voulez une clé de partition, ce qui signifie que le traitement de votre événement est partition-local .

Par exemple:

  1. Si vous vous souciez du temps moyen passé sur le site par les utilisateurs, vous devriez alors 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 que Apache Samza peut calculer le temps moyen sur site pour un utilisateur donné, en regardant simplement les événements d'une seule partition. Cela évite de devoir effectuer tout type de traitement coûteux partition-global
  2. Si vous vous souciez des pages les plus populaires de votre site Web, vous devriez partitionner par le :viewed page. Encore une fois, Samza sera capable de comptabiliser le nombre de vues d'une page donnée simplement en consultant les événements d'une seule partition.

En règle générale, nous essayons d'éviter de dépendre d'un état global (comme la gestion des comptes dans une base de données distante telle que DynamoDB ou Cassandra) et de pouvoir utiliser un état local à la partition. Cela est dû au fait que l’état local est une primitive fondamentale du traitement du flux .

Si vous avez besoin des deux cas d'utilisation ci-dessus, un modèle commun avec Kafka) consiste à partitionner en premier par say :user-id, puis à re-partitionner par :viewed prêt pour la prochaine phase de traitement.

Sur les noms de sujet - une évidence ici serait events ou user-events. Pour être plus précis, vous pouvez aller avec events-by-user-id et/ou events-by-viewed.

55
Alex Dean

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

Points clés à retenir en quelques mots:

  • En général, plus il y a de partitions dans un cluster Kafka, plus le débit peut être élevé. Laissez le maximum possible sur une seule partition pour la production p et la consommation soit 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 pour l'index et le fichier de données de chaque segment de journal. Ainsi, plus le nombre de partitions est élevé, plus il est nécessaire de 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 déjà vu une erreur dire 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 moment où un message est publié par le producteur jusqu'à sa lecture par le consommateur. En règle générale, si vous attention à 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.

5
Bitswazsky

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

Un sujet peut avoir plusieurs partitions. la partition est bonne pour le parallélisme. la partition est également l'unité de réplication, ainsi, dans Kafka, leader et suiveur sont également définis au niveau de la partition. En réalité, une partition est une file d'attente dont l'ordre est le message arrivé. Et le sujet est composé par une ou plusieurs files d'attente dans un simple mot. 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 consignés par votre serveur Web, puis envoyés au Kafka courtier par l'intermédiaire du producteur. Dans le producteur, vous pouvez spécifier la méthode de partition, par exemple: type d'événement ( é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 tout simplement aucune logique et équilibrer tous les journaux dans de nombreuses partitions.

À propos de votre cas en question, vous pouvez créer un sujet appelé "page-view-event" et créer N partitions via des clés de hachage pour répartir les journaux dans toutes les partitions de manière uniforme. Ou vous pouvez choisir une logique de partition pour que les journaux soient distribués par votre esprit.

4
GuangshengZuo