web-dev-qa-db-fra.com

Différence entre Apache Samza et Apache Kafka Streams (focus sur le parallélisme et la communication)

Dans les flux Samza et Kafka, le traitement des flux de données s'effectue dans une séquence/graphique (appelé "graphique de flux de données" dans Samza et "topologie" dans Kafka Streams) des étapes de traitement (appelées "job" dans Samza "et" processor "dans Kafka Streams). Je désignerai ces deux termes par workflow et travailleur dans le reste de cette question.

Supposons que nous ayons un flux de travail très simple, composé d'un travailleur A qui consomme des mesures de capteur et filtre toutes les valeurs inférieures à 50 suivi d'un travailleur B qui reçoit les mesures restantes et filtre toutes les valeurs supérieures à 80.

Entrée (sujet Kakfa X) -> (travailleur A) -> (travailleur B) -> sortie (sujet Kafka Y)

Si j'ai compris

correctement, les flux Samza et Kafka utilisent le concept de partitionnement de rubrique pour répliquer le flux de travail/les travailleurs et ainsi paralléliser le traitement à des fins d'évolutivité.

Mais:

  • Samza réplique chaque travailleur (c'est-à-dire un travail) séparément en plusieurs tâches (une pour chaque partition dans le flux d'entrée). Autrement dit, une tâche est une réplique d'un travailleur du flux de travail.

  • Kafka Streams réplique l'intégralité du flux de travail (c'est-à-dire la topologie) en plusieurs tâches (une pour chaque partition dans le flux d'entrée). Autrement dit, une tâche est une réplique de l'ensemble du flux de travail.

Cela m'amène à mes questions:

  1. Supposons qu'il n'y ait qu'une seule partition: est-ce correct, qu'il n'est pas possible de déployer le travailleur (A) et (B) sur deux machines différentes dans Kafka Streams alors que cela est possible dans Samza? (Ou en d'autres termes: est-il impossible dans Kafka Streams de diviser une seule tâche (c'est-à-dire une réplique de topologie) en deux machines, qu'il y ait plusieurs partitions ou non.)

  2. Comment deux processeurs ultérieurs dans une topologie Kafka Streams (dans la même tâche) communiquent-ils? (Je sais que dans Samza toutes les communications entre deux travailleurs suivants (c.-à-d., Les travaux) se font avec Kafka sujets mais comme il faut "marquer" dans Kafka Diffuse explicitement dans le code quels flux doivent être publiés en tant que Kafka sujets, cela ne peut pas être le cas ici.)

  3. Est-il exact que Samza publie automatiquement tous les flux intermédiaires en tant que Kafka sujets (et les met donc à la disposition des clients potentiels) tandis que Kafka Streams publie uniquement ces intermédiaires et flux finaux que l'on marque explicitement (avec addSink dans l'API de bas niveau et to ou through dans DSL)?

(Je suis conscient du fait que Samza peut également utiliser d'autres files d'attente de messages que Kafka mais ce n'est pas vraiment pertinent pour mes questions.)

20
Lukas Probst

Tout d'abord, dans les deux Samza et Kafka Streams, vous pouvez choisir d'avoir un sujet intermédiaire entre ces deux tâches (processeurs) ou non, c'est-à-dire la topologie peut être soit:

Entrée (sujet Kakfa X) -> (travailleur A) -> (travailleur B) -> sortie (sujet Kafka Y)

ou:

Entrée (sujet Kakfa X) -> (travailleur A) -> intermédiaire (sujet Kafka Z) -> (travailleur B) -> Sortie (sujet Kafka Y)

Dans les deux Samza ou Kafka Streams, dans le premier cas, vous devrez déployer les travailleurs A et B ensemble tandis que dans le dernier cas, vous ne pouvez pas déployer le travailleur A ou B ensemble, comme dans l'une ou l'autre des tâches du cadre, ne communiquent que par le biais de rubriques intermédiaires et il n'y a pas de canaux de communication basés sur TCP.

Dans Samza, pour le premier cas, vous devez coder vos deux filtres comme dans une tâche, et pour le dernier cas, vous devez spécifier la rubrique d'entrée et de sortie pour chacune des tâches, par ex. pour le travailleur A, l'entrée est X et la sortie est Z, pour le travail B, l'entrée Z et la sortie Y, et vous pouvez démarrer/arrêter les travailleurs déployés indépendamment.

Dans Kafka Streams, pour le premier cas, vous pouvez simplement "concaténer" ces processeurs comme

stream1.filter(..).filter(..)

et par conséquent, comme Lucas l'a mentionné, chaque résultat du premier filtre sera immédiatement transmis au deuxième filtre (vous pouvez penser à chaque enregistrement d'entrée du sujet X parcourir la topologie dans l'ordre de profondeur en premier, et il n'y a pas de mise en mémoire tampon entre les directement processeurs connectés);

Et pour ce dernier cas, vous pouvez indiquer que le flux intermédiaire doit être "matérialisé" dans un autre sujet, à savoir:

stream1.filter(..).through("topicZ").filter(..)

et chaque résultat du premier filtre sera envoyé au sujet Z, qui sera ensuite acheminé vers le deuxième processeur de filtre. Dans ce cas, ces deux filtres peuvent potentiellement être déployés sur différents hôtes ou différents threads au sein du même hôte.

9
Guozhang Wang