Débuter et avancer avec le Framework Apache Samza cours PDF
...
Définition
Apache Samza est un framework open source pour le traitement distribué des flux d'événements à fort volume. Son principal objectif de conception est de prendre en charge un débit élevé pour une large gamme de modèles de traitement, tout en offrant une robustesse opérationnelle à l'échelle gigantesque requise par les sociétés Internet. Samza atteint cet objectif grâce à un petit nombre d'abstractions conçues avec soin: journaux partitionnés pour la messagerie, état local à tolérance de pannes et planification des tâches basée sur les clusters.
Vue d'ensemble
Le traitement de flux joue un rôle de plus en plus important dans les besoins en gestion de données de nombreuses organisations. Les flux d'événements peuvent représenter de nombreux types de données, par exemple l'activité des utilisateurs sur un site Web, le mouvement de marchandises ou de véhicules ou l'écriture d'enregistrements dans une base de données.
Les travaux de traitement de flux sont des processus de longue durée qui consomment en permanence un ou plusieurs flux d'événement, invoquant une logique d'application pour chaque événement, générant des flux de sortie dérivés et éventuellement écrivant le résultat dans des bases de données pour une interrogation ultérieure. Tandis qu’un processus de traitement par lots ou une requête de base de données lit généralement l’état d’un ensemble de données à un moment donné, puis se termine, un processeur de flux n’est jamais terminé: il attend continuellement l’arrivée de nouveaux événements et ne s’arrête que s’il se termine par un événement. administrateur.
De nombreuses tâches peuvent être naturellement exprimées en tâches de traitement de flux, par exemple:
Apache Samza, un framework de traitement de flux open source, peut être utilisé pour toutes les applications ci-dessus (Kleppmann et Kreps, 2015; Noghabi et al, 2017). Développé à l'origine par LinkedIn, puis donné à la Fondation Apache Software en 2013, il est devenu un projet Apache de niveau supérieur en 2015. Samza est désormais utilisé dans la production de nombreuses sociétés Internet, notamment LinkedIn (Paramasivam, 2016) et Netflix (Netflix). Blog technologique, 2016), Uber (Chen, 2016; Hermann et Del Balso, 2017) et TripAdvisor (Calisi, 2016).
Samza est conçu pour les scénarios d'utilisation nécessitant un débit très élevé: dans certains environnements de production, il traite des millions de messages par seconde ou des milliards d'événements par jour (Feng, 2015; Paramasivam, 2016; Noghabi et al, 2017). Par conséquent, la conception de Samza donne la priorité à l’évolutivité et à la robustesse opérationnelle par rapport à la plupart des autres préoccupations.
Le cœur de Samza est constitué de plusieurs prélèvements d'assez bas niveau, au-dessus desquels des opérateurs de haut niveau ont été construits (Pathirage et al, 2016). Cependant, les abstractions de base ont été soigneusement conçues pour leur robustesse opérationnelle, et l’évolutivité de Samza est directement imputable au choix de ces abstractions de base. Le reste de cet article fournit des détails supplémentaires sur ces décisions de conception et leurs conséquences pratiques.
Traitement de journal partitionné
Un travail Samza consiste en un ensemble d'instances JVM (Java Virtual Machine), appelées tâches, qui traitent chacune un sous-ensemble des données d'entrée. Le code exécuté dans chaque machine virtuelle Java comprend la structure Samza et un code utilisateur qui implémente la fonctionnalité requise spécifique à l’application.
L'API principale du code utilisateur est l'interface Java StreamTask, qui définit une méthode process (). La figure 1 montre deux exemples de classes d'utilisateurs implémentant l'interface StreamTask. Une fois qu'un travail Samza est déployé et initialisé, la structure appelle la méthode process () une fois pour chaque message dans l'un des flux d'entrée. L'exécution de cette méthode peut avoir divers effets, notamment l'interrogation ou la mise à jour de l'état local et l'envoi de messages aux flux de sortie. Ce modèle de calcul est très similaire à une tâche de carte du modèle de programmation bien connu MapReduce (Dean et Ghemawat, 2004), à la différence que la saisie d’un travail Samza est généralement sans fin (sans limite).
Comme pour MapReduce, chaque tâche Samza est un processus mono-thread qui itère sur une séquence d'enregistrements d'entrée. Les entrées d'un travail Samza sont partitionnées en sous-ensembles disjoints et chaque partition d'entrée est affectée à exactement une tâche de traitement. Plusieurs partitions peuvent être affectées à la même tâche de traitement,
la classe SplitWords implémente StreamTask {
statique final SystemStream WORD_STREAM = new SystemStream ("kafka", "mots");
processus vide public (IncomingMessageEnvelope in,
MessageCollector out,
TaskCoordinator _) {String str = (String) in.getMessage ();
for (String word: str.split ("")) {out.send (new OutgoingMessageEnvelope (WORD_STREAM, word, 1));
}
}
}
la classe CountWords implémente StreamTask, InitableTask {private KeyValueStore <String, Integer> store;
public void init (config config, contexte TaskContext) {store = (KeyValueStore <String, Integer>) context.getStore ("nombre de mots");
}
processus vide public (IncomingMessageEnvelope in,
MessageCollector out,
TaskCoordinator _) {
Mot de chaîne = (Chaîne) in.getKey (); Integer inc = (Integer) in.getMessage ();
Nombre entier = store.get (mot); if (nombre == nul) nombre = 0; store.put (mot, nombre + inc); }
Fig. 1 Les deux opérateurs d’un compteur de fréquence de mots en flux utilisant l’API StreamTask de Samza
(Source de l'image: Kleppmann et Kreps (2015), 2015 IEEE, réutilisés avec permission)
SplitWords CountWords
Fig. 2 Une tâche Samza consomme les entrées d'une partition, mais peut envoyer des sorties à n'importe quelle partition (Source de l'image: Kleppmann et Kreps (2015), 2015 IEEE, réutilisée avec autorisation).
Fig. 3 L’état local d’une tâche est rendu durable en émettant un journal des modifications de paires clé-valeur vers Kafka (Source de l’image: Kleppmann et Kreps (2015), 2015 IEEE, réutilisée avec autorisation).
}
Dans ce cas, le traitement de ces partitions est entrelacé sur le thread de la tâche. Cependant, le nombre de partitions dans l’entrée détermine le degré maximal de parallélisme du travail.
L’interface de journal suppose que chaque partition de l’entrée est une séquence d’enregistrements totalement ordonnée et que chaque enregistrement est associé à un numéro de séquence ou un identifiant croissant de façon monotone (appelé décalage). Etant donné que les enregistrements de chaque partition sont lus de manière séquentielle, un travail peut suivre sa progression en écrivant périodiquement le décalage du dernier enregistrement lu dans la mémoire de stockage durable. Si une tâche de traitement de flux est redémarrée, elle reprend l'utilisation de l'entrée du dernier décalage enregistré.
Le plus souvent, Samza est utilisé avec Apache Kafka (voir article séparé sur Kafka). Kafka fournit un journal partitionné tolérant aux pannes qui permet aux éditeurs d'ajouter des messages à une partition de journal et aux consommateurs (abonnés) de lire les messages de manière séquentielle dans une partition de journal (Wang et al, 2015; Kreps et al, 2011; Goodhope et al. , 2012). Kafka permet également aux travaux de traitement de flux de retraiter des enregistrements précédemment vus en réinitialisant le décalage du consommateur sur une position antérieure, ce qui est utile lors de la récupération après une défaillance.
Cependant, l’interface de flux de Samza est connectable: outre Kafka, elle peut utiliser n’importe quel système de stockage ou de messagerie en tant qu’entrée, à condition que le système puisse adhérer à l’interface de journal partitionnée. Par défaut,
Samza peut également lire les fichiers du système de fichiers distribués Hadoop (HDFS) en entrée, d'une manière parallèle aux tâches MapReduce, à des performances compétitives (Noghabi et al, 2017). Sur LinkedIn, Samza est couramment déployé avec des entrées Databus: Databus est une technologie de capture de données de changement qui enregistre le journal des écritures dans une base de données et le met à la disposition des applications à consommer (Das et al, 2012; Qiao et al, 2013). Le traitement du flux d’écritures dans une base de données permet aux travaux de conserver des index externes ou des vues matérialisées sur les données d’une base de données; il est particulièrement pertinent en liaison avec la prise en charge par Samza de l’état local (voir la section
«État local tolérant aux pannes»).
Bien que chaque partition d'un flux d'entrée soit affectée à une tâche particulière d'un travail Samza, les partitions de sortie ne sont pas liées à des tâches. C'est-à-dire que lorsqu'un StreamTask émet des messages de sortie, il peut les affecter à n'importe quelle partition du flux de sortie. Ce fait peut être utilisé pour regrouper des éléments de données liés dans la même partition: par exemple, dans l'application de comptage de mots illustrée à la figure 2, la tâche SplitWords choisit la partition de sortie pour chaque mot en fonction d'un hachage du mot. Cela garantit que, lorsque différentes tâches rencontrent les occurrences du même mot, elles sont toutes écrites sur la même partition de sortie, à partir de laquelle un travail en aval peut lire et agréger les occurrences.
Lorsque les tâches de flux sont composées dans des pipelines de traitement à plusieurs étapes, la sortie d'une tâche devient l'entrée d'une autre tâche. Contrairement à de nombreux autres environnements de traitement de flux, Samza n'implémente pas sa propre couche de transport de messages pour transmettre des messages entre opérateurs de flux. Au lieu de cela, Kafka est utilisé à cette fin; Dans la mesure où Kafka écrit tous les messages sur le disque, il fournit un tampon important entre les étapes du pipeline de traitement, limité uniquement par l'espace disque disponible sur les courtiers Kafka.
En règle générale, Kafka est configuré pour conserver plusieurs jours ou plusieurs semaines de messages dans chaque sujet. Ainsi, si une étape d'un pipeline de traitement échoue ou commence à ralentir, Kafka peut simplement mémoriser l'entrée de cette étape tout en laissant un délai suffisant pour la résolution du problème. Contrairement aux conceptions de système basées sur la contre-pression, qui obligent le producteur à ralentir si le consommateur ne peut pas suivre le rythme, l'échec d'un travail Samza n'affecte pas les travaux en amont produisant ses intrants. Ce fait est crucial pour le bon fonctionnement des systèmes à grande échelle, car il permet de limiter les défaillances: dans la mesure du possible, une défaillance d’une partie du système n’a pas d’impact négatif sur les autres parties du système.
Les messages ne sont supprimés que si l'étape de traitement en échec ou lente n'est pas réparée au cours de la période de rétention du sujet Kafka. Dans ce cas, la suppression de messages est souhaitable car elle permet d’isoler le problème: la solution de remplacement, qui consiste à conserver les messages indéfiniment jusqu’à ce que le travail soit réparé, entraînerait l’épuisement des ressources (manque de mémoire ou d’espace disque), ce qui provoquerait une défaillance en cascade affectant des pièces non liées du système.
Ainsi, la conception de Samza consistant à utiliser
Les journaux sur disque de Kafka pour le transport des messages sont un facteur crucial de son évolutivité: dans une grande entreprise, un flux d’événements produit par le travail d’une équipe est consommé par un ou plusieurs travaux administrés par d’autres équipes. Les emplois peuvent être exploités à différents niveaux de maturité: par exemple, un flux produit par un travail de production important peut être consommé par plusieurs travaux expérimentaux peu fiables. L'utilisation de Kafka en tant que tampon entre les tâches garantit que l'ajout d'un consommateur peu fiable n'aura pas d'impact négatif sur les tâches les plus importantes du système.
Enfin, l'utilisation de Kafka pour le transport de messages présente un autre avantage: chaque flux de messages du système est accessible pour le débogage et la surveillance: à tout moment, un consommateur supplémentaire peut être associé pour inspecter le flux de messages.
État local tolérant aux pannes
Le traitement de flux sans état, dans lequel tout message peut être traité indépendamment de tout autre message, est facile à mettre en œuvre et à faire évoluer. Cependant, de nombreuses applications importantes exigent que les tâches de traitement de flux conservent leur état. Par exemple:
De nombreux frameworks de traitement de flux utilisent des états transitoires conservés en mémoire dans la tâche de traitement, par exemple dans une table de hachage. Cependant, cet état est perdu lorsqu'une tâche se bloque ou qu'un travail de traitement est redémarré (par exemple, pour déployer une nouvelle version). Pour rendre l'état tolérant aux pannes, certains frameworks tels qu'Apache Flink écrivent périodiquement des points de contrôle de l'état en mémoire dans la mémoire de stockage durable (Carbone et al, 2015); cette approche est raisonnable lorsque l'État est petit, mais elle devient coûteuse à mesure que l'État grandit (Noghabi et al, 2017).
Une autre approche, utilisée par exemple par Apache Storm, consiste à utiliser une base de données externe ou un magasin de clé-valeur pour tout état de processeur devant être tolérant aux pannes. Cette approche est gravement compromise en termes de performances: en raison de la latence du réseau, l'accès à une base de données sur un autre nœud est beaucoup plus lent que l'accès à un état local en cours de processus (Noghabi et al, 2017). De plus, un processeur de flux à haut débit peut facilement submerger la base de données externe de requêtes. si la base de données est partagée avec d'autres applications, une telle surcharge risque de nuire aux performances d'autres applications au point de devenir indisponible (Kreps, 2014).
En réponse à ces problèmes, Samza a mis au point une approche de gestion des états dans une tâche de flux qui évite les problèmes de points de contrôle et de bases de données distantes. L’approche de Samza visant à créer un État local tolérant aux pannes a ensuite été adoptée dans le cadre des Kafka Streams (voir l’article sur Apache Kafka).
Samza permet à chaque tâche de conserver l'état sur le disque local du nœud de traitement, avec un cache en mémoire pour les éléments fréquemment consultés. Par défaut, Samza utilise RocksDB, un magasin clé-valeur intégré chargé dans le processus JVM de la tâche de flux, mais d'autres moteurs de stockage peuvent également être branchés à sa place. Dans
Figure 1, la tâche CountWords accède à cet état géré via l'interface KeyValueStore. Pour les charges de travail avec une bonne localisation, Samza’s RocksDB avec cache fournit des performances proches des mémoires en mémoire; pour les charges de travail à accès aléatoire sur des états volumineux, il reste nettement plus rapide que d'accéder à une base de données distante (Noghabi et al, 2017).