Courtiers de messages traditionnels et données en streaming

13

Selon le site de Kafka :

" Kakfa est utilisé pour créer des pipelines de données en temps réel et des applications de streaming. "

En cherchant sur Internet au loin, j'ai trouvé la définition généralement acceptée suivante de ce que sont les " données de flux ":

  • Les données de flux sont des données qui circulent de manière contiguë d'une source à une destination sur un réseau; et
  • Les données de flux ne sont pas de nature atomique, ce qui signifie que toute partie d'un flux de données fluide est significative et traitable, par opposition à un fichier dont les octets ne signifient rien sauf si vous les avez tous; et
  • Les données de flux peuvent être démarrées / arrêtées à tout moment; et
  • Les consommateurs peuvent attacher et détacher à volonté un flux de données et n'en traiter que les parties qu'ils souhaitent

Maintenant, si tout ce que j'ai dit ci-dessus est incorrect, incomplet ou totalement faux, veuillez commencer par me corriger! En supposant que je suis plus ou moins sur la bonne voie, alors ...

Maintenant que je comprends ce que sont les «données en streaming», je comprends ce que Kafka et Kinesis veulent dire lorsqu'ils se présentent comme des middleware de traitement / courtage pour les applications avec des données en streaming. Mais cela a piqué mes intérêts: les "middlewares" comme Kafka ou Kinesis peuvent-ils être utilisés pour des données non-streaming, comme les courtiers de messages traditionnels? Et vice versa: les MQ traditionnels comme RabbitMQ, ActiveMQ, Apollo, etc. peuvent-ils / devraient-ils être utilisés pour diffuser des données?

Prenons un exemple où une application enverra son barrage constant de back-end de messages JSON qui doivent être traités, et le traitement est assez complexe (validation, transformations sur les données, filtrage, agrégations, etc.):

  • Cas n ° 1: les messages sont chacun des cadres d'un film; c'est un message JSON par image vidéo contenant les données d'image et certaines métadonnées de support
  • Cas n ° 2: Les messages sont des données chronologiques, peut-être le rythme cardiaque de quelqu'un en fonction du temps. Donc, le message # 1 est envoyé représentant mon rythme cardiaque à t = 1, le message # 2 contient mon rythme cardiaque à t = 2, etc.
  • Cas n ° 3: Les données sont complètement disparates et non liées dans le temps ou dans le cadre d'un "flux de données". Peut-être des événements d'audit / de sécurité qui se déclenchent lorsque des centaines d'utilisateurs naviguent sur les boutons de l'application et prennent des mesures

Sur la base de la facturation de Kafka / Kinesis et de ma compréhension de ce que sont les "données en streaming", elles semblent être des candidats évidents pour les cas n ° 1 (données vidéo contiguës) et n ° 2 (données de séries chronologiques contiguës). Cependant, je ne vois aucune raison pour laquelle un courtier de messages traditionnel comme RabbitMQ ne pourrait pas gérer efficacement ces deux entrées également.

Et avec le cas # 3, nous ne recevons qu'un événement qui s'est produit et nous devons traiter une réaction à cet événement. Donc, pour moi, cela signifie avoir besoin d'un courtier traditionnel comme RabbitMQ. Mais il n'y a pas non plus de raison pour que Kafka ou Kinesis ne gèrent pas non plus le traitement des données d'événement.

Donc, fondamentalement, je cherche à établir une rubrique qui dit: J'ai des données X avec des caractéristiques Y. Je devrais utiliser un processeur de flux comme Kafka / Kinesis pour le gérer. Ou, inversement, une donnée qui m'aide à déterminer: j'ai des données W avec des caractéristiques Z. Je devrais utiliser un courtier de messages traditionnel pour le gérer.

Je demande donc: quels facteurs sur les données (ou autrement) aident à orienter la décision entre le processeur de flux ou le courtier de messages, car les deux peuvent gérer les données en streaming et les deux peuvent gérer les données de message (non en streaming)?

smeeb
la source

Réponses:

5

Kafka traite des journaux ordonnés de messages atomiques. Vous pouvez le voir un peu comme le pub/submode des courtiers de messages, mais avec un ordre strict et la possibilité de relire ou de rechercher le flux de messages à tout moment dans le passé qui est toujours conservé sur le disque (ce qui pourrait être éternel).

La saveur de Kafka du streaming est opposée à l'appel de procédure à distance comme Thrift ou HTTP, et au traitement par lots comme dans l'écosystème Hadoop. Contrairement à RPC, les composants communiquent de manière asynchrone: des heures ou des jours peuvent s'écouler entre l'envoi d'un message et le moment où le destinataire se réveille et agit en conséquence. Il peut y avoir de nombreux destinataires à différents moments, ou peut-être que personne ne se souciera jamais de consommer un message. Plusieurs producteurs pourraient produire sur le même sujet à l'insu des consommateurs. Kafka ne sait pas si vous êtes abonné ou si un message a été consommé. Un message est simplement enregistré dans le journal, où toute partie intéressée peut le lire.

Contrairement au traitement par lots, vous vous intéressez aux messages uniques, pas seulement aux collections géantes de messages. (Bien qu'il ne soit pas rare d'archiver des messages Kafka dans des fichiers Parquet sur HDFS et de les interroger en tant que tables Hive).

Cas 1 : Kafka ne conserve aucune relation temporelle particulière entre producteur et consommateur. C'est un mauvais choix pour la diffusion de vidéo en continu, car Kafka est autorisé à ralentir, accélérer, se déplacer par à-coups, etc. Pour le streaming multimédia, nous voulons échanger le débit global en échange d'une latence faible et, surtout, stable (sinon connue sous le nom de faible gigue). Kafka s'efforce également de ne jamais perdre un message. Avec la vidéo en streaming, nous utilisons généralement UDP et nous nous contentons de déposer une image ici et là pour que la vidéo continue de fonctionner. Le SLA sur un processus soutenu par Kafka est généralement de quelques secondes à quelques minutes lorsqu'il est sain, de quelques heures à plusieurs jours lorsqu'il est sain. Le SLA sur les médias en streaming est en dizaines de millisecondes.

Netflix pourrait utiliser Kafka pour déplacer des images dans un système interne qui transcode des téraoctets de vidéo par heure et les enregistre sur disque, mais pas pour les envoyer sur votre écran.

Cas 2 : Absolument. Nous utilisons Kafka de cette façon chez mon employeur.

Cas 3 : Vous pouvez utiliser Kafka pour ce genre de chose, et nous le faisons, mais vous payez des frais généraux inutiles pour préserver la commande. Étant donné que vous ne vous souciez pas de la commande, vous pourriez probablement retirer des performances supplémentaires d'un autre système. Si votre entreprise gère déjà un cluster Kafka, il est probablement préférable de le réutiliser plutôt que de supporter la charge de maintenance d'un autre système de messagerie.

closeparen
la source
1
Merci @closeparen (+1) - Je reçois la plupart de ce que vous dites, à une grande exception près. Dans votre paragraphe commençant par la phrase " La saveur de Kafka du streaming est opposée ... ", je suis enclin à penser que je pourrais remplacer la plupart des exemples du mot "Kafka" par "RabbitMQ", et la phrase resterait vraie. Pour RabbitMQ: les producteurs pourraient envoyer un message et un consommateur le retirerait et le traiterait des heures / jours après. Les consommateurs peuvent se joindre à une file d'attente à tout moment, et donc pour RabbitMQ, il peut y avoir de nombreux destinataires différents à différents moments.
smeeb
1
Considérez Kafka comme un moteur de base de données avec une structure orientée journal particulière. Les producteurs ajoutent, les consommateurs lisent. La lecture n'affecte en rien l'état de Kafka. Un consommateur peut maintenir un curseur d'incrémentation pour créer une sémantique identique à RabbitMQ pub / sub, et c'est un cas d'utilisation courant, mais ce n'est pas le seul cas d'utilisation.
closeparen
1
Considérez RabbitMQ comme une version distribuée d'une structure de données de file d'attente en mémoire. Une fois que vous sortez quelque chose d'une file d'attente, il n'est plus dans la file d'attente. Bien sûr, vous pouvez avoir une topologie où il a été répliqué vers d'autres files d'attente au profit d'autres consommateurs, mais vous ne pourriez généralement pas dire «donnez-moi le message que j'ai traité il y a 500 messages» ou «démarrez la file d'attente B comme copie de la file d'attente A d'où la file d'attente A était hier. "
closeparen
2
Un système basé sur Kafka pardonne. Si vous n'aimez pas le comportement de votre programme, vous pouvez pousser un changement de code, puis rembobiner son entrée. Vous pourriez arrêter un consommateur RabbitMQ sans affecter les producteurs, mais vous ne pourriez pas revisiter le passé.
closeparen
1
Ahhh: ampoule: merci (+1 pour les 3)! C'est donc définitivement un cas convaincant pour Kafka: la possibilité de revisiter le passé. Je suppose qu'il doit y avoir une limite supérieure ou une troncature à droite? Sinon, la mémoire de Kafka ne ferait que grimper. Même si les données débordent sur le disque, les fichiers où les données de sujet sont stockées rempliraient le disque très rapidement, oui?
smeeb
5

Kafka / Kinesis est modélisé comme un flux. Un flux a des propriétés différentes de celles des messages.

  • Les flux ont un contexte pour eux. Ils ont de l'ordre. Vous pouvez appliquer des fonctions de fenêtre sur les flux. Bien que chaque élément d'un flux soit significatif, il peut l'être davantage avec le contexte qui l'entoure
  • Parce que les flux ont de l'ordre, vous pouvez l'utiliser pour faire certaines déclarations sur la sémantique du traitement. Par exemple, Apache Trident a soi-disant une sémantique exacte lorsqu'il consomme à partir d'un flux Kafka.
  • Vous pouvez appliquer des fonctions aux flux. Vous pouvez transformer un flux sans le consommer réellement. Vous pouvez paresseusement consommer un flux. Vous pouvez ignorer des parties d'un flux.
  • Vous pouvez intrinsèquement rejouer des flux dans Kafka, mais vous ne pouvez pas (sans logiciel supplémentaire) relire les files d'attente de messages. Ceci est utile lorsque vous ne savez même pas encore ce que vous voulez faire avec les données. Il est également utile pour entraîner l'IA.

En général, utilisez Kafka pour le traitement de flux hors ligne, utilisez les files d'attente de messages pour les messages client-serveur en temps réel.

Exemples de cas d'utilisation de pivot :

Kafka: suivi de l'activité du site Web, mesures, agrégation de journaux, traitement de flux, sourcing d'événements et journaux de validation

RabbitMQ: messagerie à usage général ..., souvent utilisé pour permettre aux serveurs Web de répondre rapidement aux demandes au lieu d'être obligé d'effectuer des procédures gourmandes en ressources pendant que l'utilisateur attend le résultat. À utiliser lorsque vous devez utiliser des protocoles existants comme AMQP 0-9-1, STOMP, MQTT, AMQP 1.0

Il peut parfois être utile d'utiliser les deux! Par exemple, dans le cas d'utilisation n ° 2, s'il s'agissait d'un flux de données provenant d'un stimulateur cardiaque, je demanderais à ce dernier de transmettre des données de pulsation à une file d'attente de messages RabbitMQ (en utilisant un protocole sympa comme MQTT) où elles sont immédiatement traitées pour voir si le cœur de la source bat toujours. Cela pourrait alimenter un tableau de bord et un système d'intervention d'urgence. La file d'attente de messages déposerait également les données de série chronologique dans Kafka afin que nous puissions analyser les données de pulsation au fil du temps. Par exemple, nous pourrions implémenter un algorithme pour détecter les maladies cardiaques en notant les tendances dans le flux de battements cardiaques.

Samuel
la source
1
Merci @Samuel (+1) - c'est une merveilleuse réponse et aide à mettre les choses en contexte un peu mieux. J'ai en fait quelques questions de suivi pour vous (si cela ne vous dérange pas), mais elles sont toutes articulées / subordonnées à une clarification initiale dont j'ai besoin: lorsque vous dites " Vous pouvez appliquer des fonctions aux flux. Vous pouvez transformer un flux sans réellement le consommer ... ", ces fonctions / transformations sont-elles exécutées sur Kafka , ou doivent-elles être consommées en premier avant que les flux ne soient traités via des fonctions / transformations?
smeeb
1
Ce qui signifie, vous avez KafkaProducer, Kafkaet KafkaConsumer. Disons que KafkaProducervit à l'intérieur d'une application Java, et qui KafkaConsumers'exécute sur une application / backend Ruby. KafkaProducerenvoie Message1à Kafka qui doit être transformé via Function1. Où se trouve Function1le code? Sur Kafka (approprié) ou à l'intérieur de KafkaConsumer(l'application Ruby)?
smeeb
2
Vous ne pouvez pas exécuter de fonctions ou effectuer de traitement dans Kafka lui-même. Apache Spark Streaming et Apache Storm sont deux frameworks de traitement de flux distribués qui peuvent être consommés par Kafka. Ils s'exécutent en dehors de Kafka et s'y connectent comme s'il s'agissait d'une base de données. Les frameworks exposent des fonctions utiles comme le fractionnement, l'agrégation, le fenêtrage, etc. Vous pouvez implémenter des fonctions de base dans votre consommateur Ruby, mais je recommanderais fortement l'un des frameworks. spark.apache.org/streaming storm.apache.org/releases/2.0.0-SNAPSHOT/Trident-tutorial.html
Samuel
1
OK, merci et +1 à nouveau - cela aurait été génial si Kafka avait pu faire le traitement sur les streams lui-même! Donc, pour jouer l'avocat du diable, ne pourriez-vous pas simplement demander à un consommateur RabbitMQ de retirer des messages d'une file d'attente, de les agréger en fonction de l'horodatage (ou vraiment de tout autre critère / attribut), et d'exécuter la même fenêtre et de transformer les fonctions en données que Spark Streaming ou Storm fournissent?
smeeb
1
Oui, je pense que vous pourriez le faire avec RabbitMQ car RabbitMQ a des garanties sur l'ordre des messages. Vous ne pourrez peut-être pas le faire avec chaque file d'attente de messages. Et ce serait complexe à construire. Par exemple, que se passe-t-il si votre consommateur RabbitMQ qui agrège se bloque? Avec Kafka, vous pouvez garder une trace de l'endroit dans le flux que vous avez traité, afin que vous puissiez démarrer votre consommateur au point où vous vous êtes arrêté
Samuel