Apache Kafka est-il adapté pour être utilisé comme une file d'attente de tâches?
Kafka divise les messages entrants en partitions, selon la partition assignée par le producteur. Les Messages des cloisons sont ensuite consommés par les consommateurs dans différents groupes de consommateurs.
cette architecture me fait me méfier de l'utilisation de Kafka comme file d'attente travail/tâche, parce que je dois spécifier la partition au moment de la production, qui limite indirectement ce que les consommateurs peuvent travailler sur elle parce qu'une partition est envoyée à un seul consommateur dans un groupe de consommateurs. Je préfère ne pas spécifier la partition à l'avance, de sorte que le consommateur est prêt à prendre cette tâche peut le faire. Y a-t-il un moyen de structurer les partitions/producteurs dans une architecture Kafka où les tâches peuvent être tirées par le prochain consommateur disponible, sans avoir à diviser le travail à l'avance en choisissant une partition lorsque le travail est produit?
L'utilisation d'une seule partition pour ce sujet placerait toutes les tâches dans la même file d'attente, mais alors le nombre de consommateurs est limité à 1 par consommateur groupe, de sorte que chaque consommateur devrait être dans un groupe différent. Ensuite, toute la tâche est distribuée à chaque groupe de consommateurs, ce qui n'est pas le genre de file d'attente que je recherche.
Apache Kafka peut-il être utilisé comme file d'attente?
4 réponses
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 plus élégamment.
bien que vous pouvez utiliser Kafka pour une file d'attente de tâche - vous obtiendrez quelques problèmes: Kafka ne permet pas de consommer une seule partition par de nombreux consommateurs (de par sa conception), donc si par exemple une seule partition est remplie de nombreuses tâches et que le consommateur qui possède la partition est occupé, les tâches de cette partition seront "affamées". Cela signifie également que l'ordre des la consommation des tâches dans le sujet ne sera pas 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 (en Kafka pour réaliser pleinement que vous devez avoir un seul consommateur et une seule partition - ce qui signifie la consommation en série par un seul noeud. 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-les sujets de Kafka ne sont pas des files d'attente à la manière informatique. La file d'attente signifie premier en premier - ce n'est pas ce que vous obtenez dans Kafka dans le niveau de sujet.
un Autre problème est qu'il est difficile de modifier le nombre de partitions de façon dynamique. L'ajout ou le retrait de nouveaux travailleurs doit être dynamique. Si vous voulez vous assurer que les nouveaux travailleurs obtiendront des tâches à Kakfa, vous devrez définir le nombre de partition au maximum possible des travailleurs. Ce n'est pas assez élégant.
donc l'essentiel-utiliser RabbitMQ ou d'autres Files d'attente à la place.
ayant 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
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 votre objectif final est essentiellement comment Kafka fonctionne par défaut.
Lorsque vous produisez des messages, l'option par défaut (la plus largement utilisée) est d'utiliser random partitioner, qui choisit les partitions de la manière ronde, en gardant les partitions également utilisées (de sorte qu'il est possible d'éviter de spécifier une partition).
Le but principal des cloisons est de paralléliser traitement des messages, donc vous devriez l'utiliser de cette manière.
Une autre "chose" couramment utilisée pour laquelle les partitions sont utilisées est d'assurer que certains messages sont consommés dans le même ordre qu'ils sont produits (alors vous spécifiez la clé de partitionnement de telle manière que tous ces messages finissent dans la même partition. E. g. à l'aide de userId
comme la clé assurerait que tous les utilisateurs sont traités de cette manière).
il y a deux obstacles principaux à l'utilisation de Kafka comme file d'attente de messages:
comme décrit dans réponse D'Ofer, vous ne pouvez consommer une seule partition à partir d'un seul consommateur, et l'ordre de traitement est garanti que dans une partition. Donc, si vous ne pouvez pas distribuer les tâches équitablement entre les partitions, cela pourrait être un problème
par défaut, vous ne pouvez reconnaître le traitement de tous les messages jusqu'à un point donné (offset.) Contrairement aux files d'attente traditionnelles, vous ne pouvez pas faire de reconnaissance sélective et en cas d'échec, des réessayements sélectifs. Ceci peut être une adresse en utilisant kmq, qui ajoute la capacité acks individuels à l'aide d'un sujet supplémentaire (disclaimer: i'm the author of kmq).
RabbitMQ est une alternative bien sûr, mais elle donne aussi des performances (plus faibles) et des garanties de réplication différentes. En bref, RabbitMQ docs déclarent que le courtier est pas tolérant la partition. Voir aussi notre comparaison des files d'attente de messages avec la réplication des données, mqperf.
il y a beaucoup de discussions dans ce sujet qui tournent autour de l'ordre d'exécution des tâches dans une file d'attente de travail ou de tâche. Je proposerais 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 vers l'accomplissement de tâches distinctes. Appliquer un ordre de traitement sur des tâches dans une file d'attente signifie que vous appliquez également un ordre d'achèvement sur des tâches dans la file d'attente ce qui signifie effectivement que les tâches dans la file d'attente seraient toujours traitées de façon 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âche filetée.
Si l'ordre d'exécution est important dans certaines de vos tâches, ces tâches devraient ajouter la tâche suivante dans la séquence de la file d'attente de travail après son achèvement. Soit cela, soit vous supportez un type de travail séquentiel qui, lorsqu'il est traité, traite réellement une liste de emplois séquentiellement sur un seul travailleur.
en aucun cas la file d'attente de travail ne devrait commander aucun de ses travaux - le prochain processeur disponible devrait toujours prendre la tâche suivante sans se soucier de ce qui s'est produit avant ou après la tâche terminée.
je regardais aussi kafka comme base pour une file d'attente de travail, mais plus je le Recherche, moins il ressemble à la plate-forme désirée.
je vois, il est principalement utilisé comme un moyen de synchroniser des ressources différentes et pas tant qu'un moyen d'exécuter des demandes de travail disparates.
un autre domaine qui, à mon avis, est important dans une file d'attente de travail est le soutien d'une priorisation des tâches. Par exemple, si j'ai 20 tâches dans la file d'attente, et un nouveau groupe arrive avec une priorité plus élevée, je veux que la tâche d'aller au début de la ligne pour être ramassé par un autre travailleur. Kafka ne le permettrait pas.