Elasticsearch, Architecture pour les logs

Posted on Mon 03 July 2017 in Elasticsearch

L'un des usages principaux d'Elasticsearch est le stockage de logs. Voyons sans détour comment bien architecturer et dimensionner une infrastructure complète à fin de parsing et stockage des logs.

Découpage des rôles

On peut distinguer plusieurs étapes/rôles dans une architecture ELK :

  • une étape facultative pour récupérer/centraliser les logs
  • il faut parser les logs
  • puis les stocker
  • et enfin pouvoir les consulter

L'envoi des logs

Le parsing des logs peut se faire en local sur chaque serveur. Dans le cas d'une petite infrastructure, pourquoi pas. Mais qui a envie de lancer du code JRuby sur son serveur applicatif/web/DB/whatever de production ?

Dans ce cas, le plus simple est de centraliser le parsing sur un/des serveurs qui seront dédiés à cela et ne pénaliseront pas la prod.

Le serveur qui centralisera les logs en attente de parsing sera un redis, et pour envoyer les logs vers lui, on utilisera filebeat, un petit utilitaire en Go, minimaliste pour ne pas plomber la prod.

Le parsing des logs

Nous allons partir sur un serveur dédié au parsing des logs. Cela sera le travail de Logstash.

Nous pourrions envoyer les logs directement dans Elasticsearch, mais les parser va nous permettre de chercher plus facilement dedans, de faire des stats/board, de la corrélation, etc... Autant le faire, ça vaut vraiment le coup.

Le stockage des logs

Elasticsearch est le logiciel le plus performant pour stocker et interroger des logs. Autant partir dessus.

la consultation des logs

En complément d'Elasticsearch, Kibana est le plus adapté à la consultation des logs.

Résumé

Un bon schéma vaut mieux qu'on long discours, voici ce vers quoi nous nous dirigeons. Premier schéma basique de notre infra ELK

Dimensionnement

Voici quelques estimations sur lesquelles vous pouvez vous baser pour faire un premier dimensionnement de votre architecture :

  • Logstash parse ~1000 lignes de logs par seconde par GHz de CPU
  • Elasticsearch utilise 1Mo de disque dur pour 1000 lignes de logs par jour par jour de rétention

Explicitons cela ensemble.

Redis

Le redis n'a pas forcément besoin d'être particulièrement gros. Son rôle est la centralisation des log ainsi que le buffering. Dans un cas optimal, le redis sera toujours vide car tout ce qui lui sera envoyé devrait être consommé par les logstash immédiatement.

RAM

La chose à particulièrement surveiller va être la RAM. En effet, si vous avez un pic de production de log, il faut que le redis puisse l'absorbé, le temps que les logstash consomme ce pic. Si les logstash n'arrivent pas à consommer les logs suffisamment rapidement, votre redis va exploser. Dans ce cas, il fera office de fusible.

Quand vous choissirez la taille de votre VM/serveur (RAM surtout), il faudra impérativement le mettre en perspective avec la capacité que vous allouerez à votre logstash.

Logstash/Parsing

Logstash, le service de parsing, va prendre les logs depuis le redis et les parser. Cela consistente basiquement en l'application d'une regexp pour extraire différentes informations de la ligne de log.

Ce service est stateless, car aussitôt les informations extraites, tout est envoyé dans l'elasticsearch. Logstash ne stocke aucune donnée.

Les paramètres important à regarder dans le dimensionnement d'un serveur de parsing logstash sont : le CPU (surtout) et la RAM (moins).

RAM

Evacuons tout de suite la RAM. Pourquoi faut-il se préoccuper de la RAM ? parce que vous aller tourner un logiciel écrit en JRuby. En raccourci, du Ruby interprété en Java. Oui, une JVM. C'est mieux si elle est à l'aise.

CPU

Le CPU est directement relié à la vitesse avec laquelle vos logs seront analysées. Donc, plus il y a de CPU mieux c'est. Au doigt mouillé, en première estimation, vous pouvez utiliser cette règle : Logstash parse ~1000 lignes de logs par seconde par GHz de CPU. Bien entendu, cela va dépendre de la complexité de vos règles de parsing, etc... mais c'est une bonne approximation de départ.

Parallélisation

Ce qu'il y a de bien avec un logiciel stateless, c'est que vous pouvez en démarrer autant que vous le souhaitez en parallèle, l'analyse de vos logs n'iront que plus vite. 2 serveurs 2 CPU iront 4 foix plus vite qu'un serveur 1 CPU (cadensé à la même vitesse). Pas besoin d'avoir un seul gros serveur. Plusieurs petits feront autant le travail. Sans compter sur la résilience. Mais nous verrons cela plus tard.

Elasticsearch

Elasticsearch un système de base de donnée NoSQL distribué et hautement scalable. Donc, il stocke des données. Et nous allons stocker beaucoup de données. Que devons-nous regarder pour dimensionner notre service Elasticsearch ? Le disque dur, bien évidemment ! mais aussi la RAM et dans une moindre mesure le CPU.

Pour plus de détails, vous pouvez vous reporter à la page officielle dans la doc elasticsearch.

Disque dur

Pour le stockage disque, pour faire votre dimensionnement prévisionnel, vous pouvez vous baser sur cette règle : Elasticsearch utilise 1Mo de disque dur pour 1000 lignes de logs par jour par jour de rétention. J'évacue volontairement la question de la réplication des données que nous verrons un peu plus tard. Comment appliquer cela ? Prenons comme hypothèses :

  • que vous voulez garder votre historique de log pendant 15 jours avant de le supprimer
  • que vous allez stocker les logs d'appli qui produisent en moyenne 1 millions de lignes de log par jour

Avec cela, vous allez avoir besoin de 15Go de disque dur.

RAM

Pour la RAM, il y a 2 choses à garder en mémoire : 1)Elasticsearch est codé en Java, donc vous allez faire tourner une JVM et 2) Comme toute BDD, plus vous lui fournissez de RAM, meilleures seront les performances.

Hautement distribué

Dernière chose, et qui fait la force d'Elasticsearch, c'est qu'il est totalement distribué. Si vous ne pouvez pas tout faire tenir sur un seul serveur, alors utilisez-en plusieurs, ça ne sera pas plus difficile. C'est même recommandé. Un exemple de configuration vous a été fourni, c'est la configuration que j'utilise sur un petit cluster de production de 12 serveurs.

Conclusion

Avant de plongé plus loin dans la technique et la configuration proprement dite de cette architecture, récapitulons.

Nous voulons centraliser, parser et stocker des logs dans une infrastructure "ELK".

Nous avons tout découpé en étapes unitaires et les avons isolé.

Nous avons regardé les paramètres hardware important pour le dimensionnement de notre infra pour chaque étape.

Schéma plus complet de notre infra ELK

Voici le workflow complet :

  1. Vos serveurs applicatifs/web/DB/etc... vont envoyés leurs logs à un serveur redis à l'aide de filebeat
  2. Le serveur redis concentrera les logs en faisant également office de buffer et de fusible
  3. Le/Les serveurs Logstash consommeront les logs et les analyseront avant d'envoyer le resultat du parsing au cluster elasticsearch
  4. Le cluster elasticsearch sera chargé de stocker les logs
  5. Un petit serveur kibana nous aidera à requêter les logs et à faire quelques graphiques et dashboard

Prochaine étape : faisons-le pour de vrai avec de vrais morceaux de bash et de configuration en se basant sur une vraie infrastructure ELK en production.