Le traitement à la « volée » des données massives

Avec la montée en puissance du Big Data, le problème du traitement « à la volée » (« on the fly ») des données volumineuses, vient « hanter » les architectes applicatifs, qui n’ont pas nécessairement les solutions adéquates sur lesquelles s’appuyer. Il convient au minimum de clarifier le sujet.

En 2018, les données viennent de partout et certaines d’entre elles constituent des flux massifs, qui doivent être traités en temps réel, malgré leur volume et leur fréquence d’apparition.

Spark de la galaxie Hadoop est l’une des solutions à ce problème, mais il en existe d’autres, parmi lesquelles Flink de la fondation Apache, concentre l’attention des développeurs et a déjà donné lieu à de nombreuses réalisations. Elle est l’une des plus aboutie et ne peut plus être ignorée.

 

La problématique

En matière de Big Data, on a affaire à deux natures de besoins, selon la manière dont on va traiter les données.

Le mode batch, souvent associé au concept de « dataset », par référence à un ensemble de données fini, stocké dans une base de données, est le plus connu. Dans ce cas, le problème le plus difficile à résoudre est celui du volume, avec le stockage dans une architecture distribuée et le traitement via, par exemple, la mécanique « Map and Reduce », qui fait partie de la mouvance Hadoop d’Apache.

Une fois les données stockées, il « suffit » (!!!) de connecter une couche applicative d’analyse à ces données.

L’autre mode est celui du streaming. Avec deux variantes.

La première concerne des flux de données ininterrompus, mais que le code applicatif va traiter par micro-lots (d’où leur désignation courante de micro-batch), des données regroupées selon des critères tels que le temps. Dans ce cas, le code analytique va s’appliquer à un bloc de données délimité, ce qui va induire de les stocker à la volée, dans une base temporaire ou un simple fichier texte.

Spark d’Apache est un bon exemple d’implémentation de cette architecture.

L’autre forme de streaming, consiste à traiter les données individuellement, au fur et à mesure où elles arrivent, sans chercher à les stocker, s’il n’y a pas de contraintes particulières qui le nécessitent.

Dans ce cas, il faut que les ressources de traitement soient adaptées au besoin et donc suffisamment rapides pour ne pas être débordées.

Storm et Flink sont aujourd’hui, les exemples les plus aboutis de cette forme de streaming.

Les outils de traitement des données Big Data, commencent à se densifier. Map Reduce est bien connu, avec une forte connotation batch, mais il y a aussi Spark pour le micro Batch », Storm, Tez d’Hortonworks et surtout Flink. Tous ces outils constituent une couche homogène entre la gestion des ressources et le niveau applicatif.

 

Le « streaming »

En 2018, le streaming non limité est en pleine progression et représente déjà 10 % des architectures opérationnelles. Eu égard essentiellement à ce que la prise de décision est de plus en plus souvent effectuée en temps réel, concurrence oblige.

C’est par exemple le cas de données issues de capteurs de sécurité placés dans des usines et remontées à une centrale de supervision, qui exécutent des traitements, si elles sont dégradées, incomplètes, aberrantes ou insuffisamment précises (par exemple).

C’est aussi le cas d’un site de e-commerce, dont près de 5 % des ventes ne se font pas, faute à des problèmes intervenus pendant le processus de paiement. Si l’équipe de supervision est informée en temps réel qu’un client est en train de « patauger » pour payer sa commande, elle pourra intervenir, lui proposer de l’aider à finaliser l’acte d’achat. Certaines enseignes confrontées à cet écueil, estiment que le taux de perte des commandes, peut ainsi tomber à 1 %.

Globalement les besoins de traitement en temps réel augmentent fortement, pour enregistrer des logs et les activités d’utilisateurs mobiles, par exemple, pour traiter des opérations financières qui ont besoin d’ « immédiateté », pour récupérer les données issues de voitures autonomes, qui ne peuvent évidemment pas attendre, etc.

La chaîne de traitement spécifique du Big Data temps réel, avec son découpage en trois grandes phases : la capture des données non limitées, la logique de traitement « à la volée » et les traitements en aval, parmi lesquelles les restitutions statistiques.

 

Les architectures « possibles »

Il existe actuellement plusieurs architectures susceptibles de répondre au besoin de traitement des données en streaming. Ce sont des montages, le plus souvent Apache, qui au-delà du stream, sont capables de prendre en compte des besoins batch ou micro-batch.

Généralement, il s’agit d’un empilement d’outils et d’API, plus ou moins spécifiques, à connotation « projet », dont il convient de retenir plus l’esprit, que la nature des composants.

Dans l’absolu de quoi avons-nous besoin ? :

  • d’une couche de récupération des données, l’interface avec les fournisseurs, celles-ci étant générées en continu, sans limites. Ces données pouvant venir de capteurs, mais aussi d’applications.
  • d’une couche de « préparation » des données, un intermédiaire entre le flux de données et leur mise à disposition applicative. Le « broker » Kafka, mais aussi Kinesis, sont des solutions très prisées en 2018.
  • d'une logique de traitement temps réel, sur les données prises individuellement ou regroupées en mini-batch.

Historiquement, la première architecture Big Data dédiée à ces exigences a été celle de Nathan Marz, dite Lambda, constituée d’une couche batch, d’une couche temps réel (Speeding), pour laquelle Marz recommandait les outils Apache Storm ou Spark et une couche de service, pour préparer les données en vue de leur traitement ultérieur (HBase, Cassandra ou ElasticSearch). Dans cette architecture, la couche « speeding » n’est pas la plus importante et surtout les données doivent être traitées deux fois, selon le processus retenu, batch ou temps réel.

Jay Kreps s’est basé sur Lambda pour imaginer une solution (Kappa) plus conforme aux besoins du streaming (voir son désormais célèbre article « Questioning the lambda architecture ») et a fusionné les deux couches en privilégiant le traitement des données, au détriment du stockage (base de données « immutable »).

Ces architectures ont aujourd’hui plus valeur historique que de référence. Elles ont cependant été et continuent à être utilisées, mais sont progressivement remplacées par des concepts plus modernes, mieux adaptés aux contraintes actuelles.

 

L’architecture de Flink

Flink, à l’origine le projet Stratosphere, est né à l’université de Berlin en 2008 (Pr Volker Marl) et il est maintenant hébergé chez Apache, comme nombre de projets majeurs.

Flink , dont on parle beaucoup, présente lui-aussi un double visage, selon que les données volumineuses qu’il traite, sont accessibles en batch ou en temps réel, en streaming. Dans le premier cas, il est un peu le pendant de Map Reduce, mais c’est surtout le deuxième aspect qui nous intéresse ici. Flink apparaissant sans doute, comme l’une des solutions les plus pertinentes sur ce créneau très particulier, mais devenu oh combien important par les temps qui courent…

Concrètement, il faut voir Flink comme un serveur intermédiaire, capable d’effectuer des traitements sur des données ininterrompues, tâches qu’il permet de lancer et de suivre en temps réel.

En aval et du point de vue développement, Flink est connectable à différentes briques applicatives, parmi lesquelles SAMOA pour intégrer des fonctions de Machine Learning dans les processus ou Dataflow, pour l’analyse de graphes en temps réel, etc.

Du point de vue structure, Flink est constitué de deux acteurs principaux, un « JobManager » et un ou plusieurs « TaskManagers », déployés sur une machine unique, un cluster local (pour le développement et la mise au point) et plus fréquemment sur des machines différentes, dans un cluster « normal ». Des ingrédients d’architectures, qui ne sont pas sans rappeler ceux de « Map and Reduce », l’architecture de traitement batch d’Hadoop. On voit bien que l’on est dans la même mouvance Hadoop.

Le cœur du système, est donc le « JobManager », dont le travail est de planifier les tâches (« threads »), de les distribuer aux « TaskManagers » disponibles, de suivre l’exécution des traitements et de compiler les résultats. Par défaut, il n’y a qu’un seul « JobManager », ce qui lui est reproché, mais grâce au framework ZooKeeper, il est possible d’en prévoir plusieurs, un actif et des « TaskManagers » en attente, prêts à prendre le relais en cas de difficultés.

Chaque « TaskManager », enfin, est susceptible d’héberger un ou plusieurs « Task Slot », des emplacements mémoires, destinés à recevoir les « threads ».

Pour garantir la continuité de service et pallier à certains dysfonctionnements, il est possible d’activer le mode « checkpoint », de manière à ce que Flink prenne des instantanés des applications à intervalles réguliers et soit capable de les redémarrer à partir du dernier « checkpoint », tout en respectant la position de chacune des tâches (Exactly-Once Processing Delivery Guarantee).

Il y a deux manières de lancer les travaux, soit en ligne de commande avec le mode CLI (Command-Line Interface), soit par un client Web sur le port 8080, qui permet de soumettre les jobs, de les exécuter, de mettre au point les plans d’exécution et d’avoir une vision globale du cluster.

Le « JobManager » peut être surveillé via une interface spécifique, le « JobManager Web Interface » sur le port 8081, pour suivre la progression des traitements, consulter le détail des travaux, suivre la consommation des ressources par les « TaskManagers » et avoir une vision complète du comportement de Flink.

Pour le traitement d’un flot « streaming » de données, Flink s’appuie essentiellement sur un « Stream Builder », un runtime distribué pour le traitement et une API « Stream Processing DataStream » dédiée. Comme le montre ce schéma, Flink bénéficie de différents modes de distribution du traitement, selon qu’il va fonctionner en local, en cluster local ou distribué, le « travail » étant effectué par les principaux utilitaires du marché : Docker, YARN, Tez, Mesos, etc, dont ceux destinés au Cloud et sur une large diversité de plates-formes logiques de stockage, HDFS, S3 (AWS), SQL, NoSQL (MongoDB, HBase…), Flume, Kafka, RabbitMQ, etc. Cette diversité d’intégration est l’une de ses caractéristiques les plus appréciées.

 

La logique développement du streaming Flink

Avec Flink, les flux de données non limitées sont des streams constitués d’items, sur lesquels portent des transformations, qui produisent en sortie un ou plusieurs flux. Totalement indépendant de la nature et du format des éléments qui lui sont soumis, Flink peut fonctionner, soit directement sur les data, soit passer par l’intermédiaire d’une clé, qui peut être l’un des sous-éléments d’un élément entrant ou la concaténation de certains de ces sous-éléments.

La mise en œuvre de Flink se fait généralement en Java, mais on peut aussi utiliser des « wrappers » qui lui permettent d’enrober du code Python ou Scala (fonctionnel), très adaptés au traitement des séries ininterrompues. De plus, Flink dispose d’un langage de requête spécifique, Flinq QL, qui agit sur l’API Table, avec des fonctionnalités proches de Pig, le langage de requête batch de Hadoop ainsi que de SQL.

Lors d’un traitement continu, l’API DataStream permet d’effectuer un grand nombre d’opérations, parmi lesquelles :

Map : applique une transformation à chaque élément du flux

Filter : filtre les éléments sous certaines conditions

KeyBy : attribue une clé aux éléments d’un flux, qui en sortie devient de type KeyedDataStream

Aggregations : des fonctions sum, max, min, maxBy et minBy, portant sur des éléments agrégés d’un KeyedDataStream

Union : union de plusieurs flux, qui inclut tous les champs, sans se préoccuper des doublons

Split : partitionne un flux entrant selon certains critères

Select : sélectionne un ou plusieurs éléments d’un flux partitionné

Extract Timestamps : récupère l’horodatage d’un flux

Au-delà des données traitées individuellement, Flink est susceptible d’agir sur des séries finies de données. Il se fonde pour cela sur un mécanisme de fenêtres, fondées par exemple sur un critère temps, les 5 prochaines secondes ou sur les données elles-mêmes, des séquences de 10 ou 15 données successives. Ces fenêtres peuvent être agencées de différents manières, sans chevauchement (TumblingWindow), glissantes (SlidingWinbdows) ou par sessions, avec des périodes d’attente.

 

Pour progresser

De nombreux documents ont été publiés sur ce sujet, parfois abscons et contradictoires. L’un des meilleurs est incontestablement celui de Philippe Rigaux, professeur des universités au CNAM (ici). Qui couvre toutes les problématiques de bases de données appliquées au Big Data, bases SQL, bases NoSQL, recherche d’informations, calcul distribué, etc. Ce document est publié sous licence Creative Commons.

Avec l’augmentation de la puissance de calcul des processeurs répartis dans un cluster et leur capacité à comporter des nœuds dédiés à certains traitements comme le « Machine Learning » et le graphique, les architectures capables de traiter des flux importants de données en mode streaming, vont se développer, au détriment du batch. Sachant que c’est là une forme d’usage très répandue et qu’il convient de la traiter nativement, plutôt que de passer par des architectures de substitution ou dépassées (lambda ou Kappa).

Les solutions vont se diversifier, qui vont quitter le domaine quasi-exclusif d’Apache et de l’Open Source Hadoop, la conséquence du déferlement des systèmes de capteurs et d’IoT, les grands « clients » de ces architectures.

Nous percevons ce streaming Big Data, comme l’un des grands chantiers à venir, qui va constituer une spécialité très recherchée, à des niveaux de salaire motivants, pour ceux qui auront pris la précaution de se former. Courage à eux, car le sujet est tout sauf simple.