I. Le contexte▲
Bien souvent, quand on parle de logs, c'est pour en déplorer l'absence. Mais imaginez à présent la situation inverse où vous auriez tellement de traces qu'au final il ne serait plus possible d'en extraire la moindre information.
Cette situation Pablo Lopez (architecte technique) l'a vécue. Et c'est au cours d'une présentation au Devoxx France 2012 qu'il nous a exposé la solution à ce raz-de-marée de traces.
Tout d'abord parlons chiffres. Les traces mentionnées ici proviennent d'un site Web marchand traitant environ 61 millions de commandes/an avec des pics d'activité montant jusqu'à 10 commandes par seconde.
Ce site représente 500 serveurs en production faisant tourner 80 applications à raison de cinq JVM par serveur en moyenne. Rajoutez par dessus jusqu'à 13 niveaux de load-balancing et vous comprendrez pourquoi il est au final quasiment impossible de suivre le parcours d'un utilisateur tout au long de sa navigation.
Trois niveaux de logs cohabitent :
- les logs techniques qui regroupent les exceptions techniques, les temps de réponse par fonction, etc. ;
- les logs fonctionnels qui indiquent les opérations réalisées par les utilisateurs. Exemple : l'utilisateur a finalisé une commande pour un montant de x euros :
- les logs analytiques qui répondent à des problématiques telles que “Sachant que l'on a présenté à l'utilisateur la publicité P, quel a été le taux de conversion ?”.
Malheureusement avec une moyenne de sept Go par serveur et par jour on se rend compte que :
- la rotation des fichiers est trop rapide et un fichier ne couvre pas plus de 30 minutes d'activité du site ;
- les transferts sont fastidieux et encombrent le réseau du fait de leur taille :
- l'analyse doit se faire sur des données éparpillées : pas de fil d'Ariane pour suivre un utilisateur au fur et à mesure de sa navigation.
Tous ces facteurs dégradent et retardent la prise de décision alors que parfois la situation est critique et exige une réponse immédiate.
Partant de ces constats Pablo et son équipe ont alors enclenché une vraie réflexion sur cette problématique.
II. La solution▲
Le résultat de la réflexion des équipes d'architecture peut se résumer sous la forme de six items que nous allons vous présenter en précisant à chaque fois la solution technique associée.
II-A. Centraliser▲
À cause du nombre de serveurs, du nombre d'applications et du load-balancing, il convenait de simplifier et de regrouper l'accès aux logs.
La première action menée fut de ne plus stocker les fichiers de log en local mais de les faire transiter sur le réseau et de les agréger en un seul point. Le but était donc de rapatrier peu mais souvent à l'inverse du process d'origine qui ramenait beaucoup mais uniquement à la demande.
Pour cela ils firent appel à Syslog-NG, un logger réseau configuré pour envoyer les évènements sous forme de trames UDP. Le choix de trames UDP s'imposait pour des raisons de performances mais introduisait l'éventualité de perdre des trames. Or, perdre de l'information n'était pas une option.
II-B. Sécuriser▲
Pour contrer la possible perte de trames UDP, chaque serveur reçoit un logger Syslog-ng local dont le contenu était collecté un peu plus tard par un autre logger Syslog-ng. Ce collecteur est distant et utilise des trames TCP.
Malheureusement une fois la question du transit sur le réseau réglée, on constata que le NAS chargé d'agréger les logs récoltés, était poussé dans ses retranchements.
Étant donné la volumétrie traitée, Apache Hadoop et son système de fichier HDFS (Hadoop Distributed File System) semblaient offrir les qualités requises pour le traitement. Pourtant il était impossible à Syslog-ng d'écrire nativement dans le HDFS d'Hadoop. Il fallait donc trouver un moyen d'insérer le contenu ramené par Syslog-ng. C'est alors que Flume entre en scène.
Flume n'est rien d'autre qu'un service dédié à l'écriture de larges volumes de données vers HDFS, répondant donc parfaitement à la problématique de transfert des logs de Syslog-ng vers Hadoop. Une fois les données persistées dans Hadoop il ne reste alors plus qu'à profiter des fonctionnalités natives de HDFS.
En effet, à partir d'un nœud central (Name Node), les données sont coupées en morceaux (chunks) puis réparties/dupliquées sur les nœuds du réseau.
Cette solution permet donc de se passer d'une réplication matérielle (RAID) puisque c'est le système de fichier lui-même qui assure la réplication/duplication.
Pablo émettra cependant un bémol face à cette situation presque idyllique, en précisant qu'à l'heure actuelle, il n'existe pas de version High Disponibility pour le Name Node et que la perte de ce dernier peut se révéler plus que problématique. De même, l'accès aux fichiers dont la taille est inférieure à la taille du chunk est moins performante.
II-C. Analyser▲
Après avoir inséré et sécurisé les données au sein de l'HDFS, l'analyse des logs devient relativement standard dans le sens où il ne s'agit plus alors que de définir un job de type Map/Reduce.
La partie Map du job est utilisée pour filtrer les informations afin de constituer l'ensemble des données à analyser. Par exemple extraire les montants facturés pour le serveur X sur une période.
La partie Reduce, quant à elle, regroupe au fur et à mesure les résultats du traitement appliqué à l'ensemble des données pertinentes issues de la partie Map (cf. MapReduce pour plus d'infos).
Hadoop et HDFS étant nativement distribués, ce sont donc tous les nœuds du cluster qui participent à l'analyse. Les données ainsi obtenues n'ont alors plus qu'à être sauvegardées dans l'attente de leur exploitation.
II-D. Informer▲
Une fois la phase d'analyse terminée on pourrait être tenté de se dire que le plus dur est passé et qu'il ne reste plus qu'à afficher le résultat. Hélas ce n'est pas aussi simple.
Même si au final les données analysées sont beaucoup moins volumineuses que les données brutes, elles restent d'une taille conséquente et il serait impossible de les exploiter en l'état.
Après avoir envisagé dans un premier temps une solution à base de SGBD Oracle, une solution basée sur MongoDB a finalement été mise en place pour des raisons :
- de coût (la solution Oracle aurait été prohibitive) ;
- d'élasticité du modèle ;
- d'exploitation du format de la réponse (JSON) ;
- de maturité du langage de requêtage.
Enfin, pour assurer la représentation, le framework Play! a été choisi pour sa capacité à manipuler aisément les données JSON fournies par MongoDB auquel il s'interface très facilement.
II-E. Archiver/Comparer▲
Dans le cadre d'une activité commerciale et saisonnière il s'avère utile de disposer d'indicateurs sur les habitudes de consommation ou sur le volume de commandes. On peut vouloir, par exemple, comparer le volume de commandes à différents intervalles (fêtes de fin d'année entre autres).
Mais disposer d'un outil de comparaison peut aussi servir à établir un bilan de santé des serveurs en donnant la possibilité de comparer l'activité serveur par serveur.
Encore une fois c'est Hadoop qui fournit la solution en permettant la mise en place de nouveaux algorithmes de Map/Reduce selon les critères voulus.
II-F. Temps réel▲
Ainsi qu'évoqué en début d'article, si une alerte apparaît dans les logs mais que cette dernière n'est pas remontée dans un délai raisonnable, on perd tout ou partie de sa capacité de réaction. De plus le processus de remontée et d'analyse des logs ne doit pas devenir un frein à l'activité de ce qu'il surveille.
Sur ce dernier point Pablo ne cache pas que c'est certainement la partie du contrat la plus difficile à respecter. Ainsi, dans les premières versions de l'architecture présentée, le traitement d'une seule minute d'activité prenait près de 45 minutes avant de pouvoir être finalement disponible. Ce n'est qu'au prix d'optimisations laborieuses et parfois radicales que le temps de traitement d'une minute de log a pu descendre sous la barre des deux minutes.
III. Et l'avenir dans tout ça ?▲
Pour Pablo et son équipe l'avenir se passe à différents niveaux :
- créer de nouveaux rapports d'analyse qui serviront à décharger progressivement une base relationnelle ;
- affiner le suivi de la navigation de l'utilisateur et notamment les chemins empruntés par les robots de référencement lorsqu'ils calculent la visibilité du site ;
- arriver à mettre en place la haute disponibilité à tous les niveaux de l'architecture ;
- proposer une analyse en direct via une interface de requête (mais ceci suppose de pouvoir développer des algorithmes de Map/Reduce paramétrables dynamiquement) ;
- rester vigilant sur l'évolution des produits employés, car la maturité n'est pas encore forcément au rendez-vous (notamment pour Hadoop).
IV. Conclusion▲
Nous avons été agréablement surpris par le contenu de cette présentation qui s'appuyait sur un cas très concret d'utilisation d'Hadoop. Le fait de découvrir une problématique autre que celle d'applications déployées dans le cloud par les Google, Facebook, Amazon et consorts était pour le moins plaisant.
Avec une problématique suffisamment concrète, à laquelle chacun peut s'identifier et grâce à un propos clair, poussé mais sans fioritures, cette conférence rentre aisément dans le top 5 de nos présentations préférées lors de ce Devoxx France 2012.
Pour vous faire votre propre avis vous pouvez retrouver les slides de cette présentation ici.
V. Remerciements▲
Cet article a été publié avec l'aimable autorisation de la société SoatSoat.
Nous tenons à remercier jacques_jean pour sa relecture attentive de cet article et Mickael Baron pour la mise au gabarit.