Kafka divise les messages entrants en partitions, en fonction de la partition attribuée par le producteur. Les messages des partitions sont ensuite consommés par les consommateurs de différents groupes de consommateurs.
Cette architecture me fait hésiter à utiliser Kafka comme file d'attente de travail/tâche, car je dois spécifier la partition au moment de la production, ce qui limite indirectement le nombre d'utilisateurs qui peuvent y travailler car une partition est envoyée. Je préférerais ne pas spécifier la partition à l’avance, de sorte que le client disponible pour cette tâche puisse le faire. Existe-t-il un moyen de structurer des partitions/producteurs en Kafka où les tâches peuvent être extraites par le prochain consommateur disponible, sans avoir à fractionner le travail à l'avance en choisissant une partition lors de la production du travail?
L'utilisation d'une seule partition pour cette rubrique placerait toutes les tâches dans la même file d'attente, mais le nombre de consommateurs étant limité à 1 par groupe de consommateurs, chaque consommateur devrait appartenir à un groupe différent. Ensuite, toute la tâche est distribuée à chaque groupe de consommateurs, ce qui n’est pas le type de file d’attente de travail que je recherche.
Apache Kafka est-il approprié pour être utilisé comme file d'attente de tâches?
Utiliser Kafka pour une file d'attente de tâches est une mauvaise idée. Utilisez plutôt RabbitMQ, il le fait beaucoup mieux et avec plus d'élégance.
Bien que vous puissiez utiliser Kafka pour une file d'attente de tâches - vous obtiendrez certains problèmes: Kafka ne permet pas de consommer une partition unique par de nombreux consommateurs (par conception) Ainsi, si, par exemple, une seule partition est remplie de nombreuses tâches et que le client propriétaire de la partition est occupé, les tâches de cette partition obtiendront la "famine". Cela signifie également que l'ordre de consommation des tâches du sujet ne sera pas modifié. identique à l'ordre dans lequel les tâches ont été produites, ce qui pourrait causer de graves problèmes si les tâches doivent être consommées dans un ordre spécifique (dans Kafka pour que vous deviez réaliser entièrement que vous ne devez avoir qu'un seul consommateur et une seule partition - ce qui signifie la consommation en série par un seul nœud. Si vous avez plusieurs consommateurs et plusieurs partitions, l'ordre de consommation des tâches ne sera pas garanti au niveau du sujet).
En fait - Kafka les sujets ne sont pas des files d'attente à la manière de l'informatique. Queue signifie Premier entré, premier sorti - ce n'est pas ce que vous entrez Kafka dans le sujet niveau.
Un autre problème est qu’il est difficile de changer le nombre de partitions de manière dynamique. L'ajout ou la suppression de nouveaux travailleurs doit être dynamique. Si vous voulez vous assurer que les nouveaux travailleurs auront des tâches dans Kakfa, vous devrez définir le nombre de partitions sur le nombre maximal de travailleurs possibles. Ce n'est pas assez élégant.
La ligne du bas - utilisez plutôt RabbitMQ ou d’autres files d’attente.
Après avoir dit tout cela - Samza (par linkedin) utilise kafka comme une sorte de file d'attente de tâches basée sur la diffusion en continu: Samza
Edit: considérations d'échelle: j'ai oublié de mentionner que Kakfa est un outil Big Data/Big scale. Si votre taux de travail est énorme, alors Kafka pourrait être une bonne option pour vous en dépit de ce que j'ai écrit plus tôt, car traiter avec une taille énorme est très difficile et Kafka est très bien dans ce domaine. Si nous parlons d’échelles plus petites (disons, jusqu’à quelques dosens/centaines d’emplois par seconde), puis encore Kafka est un mauvais choix par rapport à RabbitMQ.
Je dirais que cela dépend de l'échelle. Combien de tâches prévoyez-vous dans une unité de temps?
Ce que vous décrivez comme objectif final concerne essentiellement le fonctionnement par défaut de Kafka.). Lorsque vous produisez des messages, l’option par défaut (la plus largement utilisée) consiste à utiliser un partitionneur aléatoire, qui choisit les partitions à la ronde. , en gardant les partitions utilisées uniformément (il est donc possible d’éviter de spécifier une partition).
Le but principal des partitions est de paralléliser le traitement des messages, vous devriez donc l'utiliser de cette manière.
Une autre "chose" couramment utilisée pour les partitions est de s'assurer que certains messages sont consommés dans le même ordre de production (vous spécifiez ensuite la clé de partitionnement de sorte que tous ces messages se retrouvent dans le même Par exemple, utiliser userId
comme clé garantirait que tous les utilisateurs soient traités de cette manière).
Il y a beaucoup de discussions dans cette rubrique autour de l'ordre d'exécution des tâches dans une file de travail ou de tâches. J'avancerais l'idée que l'ordre d'exécution ne devrait pas être une caractéristique d'une file d'attente de travail.
Une file d'attente de travail est un moyen de contrôler l'utilisation des ressources en appliquant un nombre contrôlable de threads de travail à l'achèvement de tâches distinctes. L'application d'un ordre de traitement aux tâches d'une file d'attente signifie que vous appliquez également un ordre d'achèvement aux tâches de la file d'attente, ce qui signifie que les tâches de la file d'attente seront toujours traitées de manière séquentielle, la tâche suivante n'étant traitée qu'après la fin de la tâche précédente. Cela signifie effectivement que vous avez une seule file d'attente de tâches à thread.
Si l'ordre d'exécution est important dans certaines de vos tâches, celles-ci doivent ajouter la tâche suivante de la séquence à la file d'attente des tâches une fois celle-ci terminée. Soit vous prenez en charge un type de travail séquentiel qui, une fois traité, traite en réalité une liste de travaux séquentiels sur un travailleur.
La file d'attente de travail ne doit en aucun cas ordonner son travail. Le prochain processeur disponible doit toujours exécuter la tâche suivante, sans tenir compte de ce qui s'est passé avant ou après son achèvement.
Je cherchais aussi kafka comme base pour une file d’attente de travail, mais plus je la recherche, moins elle ressemble à la plate-forme souhaitée.
Je le vois principalement utilisé comme un moyen de synchroniser des ressources disparates et pas tellement comme un moyen d’exécuter des demandes de travail disparates.
Un autre domaine que j'estime important dans une file d'attente de travail est la prise en charge d'une hiérarchisation des tâches. Par exemple, si j'ai 20 tâches dans la file d'attente et qu'une nouvelle tâche arrive avec une priorité plus élevée, je souhaite que cette tâche passe au début de la ligne et soit reprise par le prochain opérateur disponible. Kafka ne le permettrait pas.
Tenter d'utiliser Kafka comme file d'attente de messages) constitue un obstacle majeur:
comme décrit dans Réponse d'Ofer , vous ne pouvez utiliser qu'une seule partition à partir d'un seul consommateur et l'ordre de traitement n'est garanti que dans une partition. Donc, si vous ne pouvez pas répartir les tâches équitablement sur les partitions, cela peut poser problème
par défaut, vous ne pouvez accuser réception que du traitement de tous les messages jusqu'à un point donné (décalage). Contrairement aux files d'attente de messages traditionnelles, vous ne pouvez pas effectuer d'accusé de réception sélectif ni, en cas d'échec, de nouvelles tentatives sélectives. Ceci peut être résolu en utilisant kmq , ce qui ajoute une capacité d'acks individuelle à l'aide d'un sujet supplémentaire (disclaimer: je suis l'auteur de kmq).
RabbitMQ est bien sûr une alternative, mais il offre également des performances (inférieures) et des garanties de réplication différentes. En bref, les documents RabbitMQ indiquent que le courtier n'est pas tolérant aux partitions . Voir aussi notre comparaison des files de messages avec la réplication de données, mqperf .