Affichage des articles dont le libellé est bench. Afficher tous les articles
Affichage des articles dont le libellé est bench. Afficher tous les articles

mardi 1 octobre 2013

Quelques benchs sur Logstash et ElasticSearch

Voilà, je n'ai pas pu y résister. L'autre jour, j'étais tranquillement en train de traîner dans la tribune de rédaction de linuxfr et j'ai aidé à rédiger un article sur ma nouvelle lubie : Logstash, ElasticSearch et Kibana. L'article est relativement pédagogique mais ne pousse pas la réflexion plus loin que la mise en place. Il aurait été intéressant d'ajouter quelques benchs.

Comme de mon côté, je n'avais pas vraiment eu l'occasion de trop pousser le produit non plus (juste au travers un petit POC pas super poussé en terme de volumétrie) je me suis dit qu'après tout ça serait l'occasion de le faire.

Les conditions du test

Comme vous savez sûrement, j'attache énormément d'importance à la pensée Cartésienne. Pour se faire je me dois de vous donner quelques caractéristiques sur la machine sur laquelle je travaille. En voici quelques-unes (ne pas hésiter à me signaler des manquements) :
  • Processeur : AMD Phenom(tm) II X4 965 Processor ;
  • Mémoire : 8 Go - Swap : 8 Go ;
  • Java : OpenJDK (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.13.04.2) ;
  • Taille du fichier : 167997125 (~ 160 Mo) ;
  • Nombre de ligne : 1354848.
Attention : les benchs qui vont être réalisés plus loin sont fait par un néophyte sur ces produits. Si vous pensez que j'ai pu faire des erreurs, n'hésitez pas à me les signaler !

Quelques benchs

Les premiers pas

Pour me faire une idée de la capacité de traitement de logstash, j'ai voulu démarrer par un test très simple : en entrée une socket d'écoute simple et la sortie dans un fichier sans aucun traitement dessus. Pour mémoire, voici le fichier de configuration (bench.conf) que j'ai utilisé :

# Écoute sur le port 2048 de la machine
input {
  tcp {
    port => 2048
  }
}
# Balance le JSON obtenue dans un fichier
output {
  file {
    path => "./bench.json"
  }
}

Le lancement de logstash se fait avec la commande suivante :

java -Xms256m -jar logstash-1.2.1-flatjar.jar agent \
     -f bench.conf

Il ne me reste plus qu'à injecter le contenu de mon fichier dans la socket - ce que je fais à l'aide de la commande nc (netcat) - précédé par la commande time pour avoir une idée du temps que je mets :

time cat /var/log/syslog.1 | nc localhost 2048

Grosso modo, j'arrive donc à un temps de traitement de 41 secondes (soit environ 4 Mo/s ou encore 33045 lignes/s).

Voyons maintenant quelque chose de plus proche de la réalité.

Injection dans un moteur ElasticSearch

J'ai tout d'abord utilisé le moteur ElasticSearch embarqué. La configuration était la suivante :

output {
  elasticsearch {
    embedded => true
  }
}

En lançant le bench, j'obtiens une injection en environ 144 secondes.

Injection dans un moteur ElasticSearch externe

Ici, on va simplement configurer un moteur ElasticSearch afin de le faire tourner dans un process séparé. La configuration est relativement simple puisque nous allons reprendre celle par défaut. Une fois décompresser, le lancement se fait donc avec la commande suivante :

./bin/elasticsearch -f

NB : On procédera également à la suppression des données du moteur entre deux lancements du bench afin d'éviter une influence sur le résultat.

Enfin, du côté de logstash, nous allons simplement modifié la section output de la configuration de la manière suivante :

output {
  elasticsearch {
    host=> "robert"
    cluster => "elasticsearch"
    embedded => false
  }
}

En relançant le traitement, nous obtenons 113 secondes. Bonne nouvelle, c'est mieux.

Quelques modifications de paramètres sur Logstash

Essayons de buffuriser un peu nos écritures afin de voir l'impact que ça pourrait avoir. Le premier sera le paramètre flush_size (nombre maximum d'événement à flusher, par défaut 100). Voici l'impact sur le temps de traitement en fonction de sa valeur :
  • 200 : 114 secondes ;
  • 1000 : 110 secondes ;
  • 10000 : 105 secondes ;
  • 100000 : 101 secondes ;
  • 1000000 : 105 secondes.
Le gain est relatif et on peut voir que nous arrivons à un plafond au delà duquel, nous n'avons plus du tout d'impact sur les performances.

On va maintenant se pencher sur le paramètre idle_flush_time (temps maximum d'attente entre deux flushs, par défaut à 1 seconde). Ici encore, voyons l'impact sur les performances (avec un flush_size à 100000) :
  • 2 s : 104 secondes ;
  • 4 s : 107 secondes.
Bref, ça s'améliore pas. Donc de ce côté ci, on va arrêter les recherches !

Quelques modifications sur ElasticSearch

On va tout d'abord essayer d'espacer les flushs sur disque en bougeant le paramètre index.translog.flush_threshold_period (temps entre deux commits, par défaut 30m). En le passant à 5 s, nous baissons le temps de traitement à 99 secondes.

J'ai ensuite essayé divers modifications en suivant le document suivant : https://gist.github.com/duydo/2427158. Malheureusement, je n'ai jamais trouvé d'autre levier suffisamment efficace pour améliorer les choses. Il semblerait que ma machine manque de puissance pour pouvoir aller plus loin.

Pour conclure

Le but de ce bench était de se faire une idée de la capacité de traitement de notre ami Logstash et de son copain ElasticSearch sur une machine seule. Pour résumer, il faut tout de même se dire qu'on est en mesure de traiter environ 16 000 lignes / secondes ou 1,6 Mo / secondes (ce qui n'est pas mal du tout !). Même si j'ai déjà vu des choses particulièrement atroces qui devait pas être loin de cette volumétrie, je pense que ces produits ont du potentiel.

Autre point, nous sommes sur une infrastructure non distribué avec l'indexeur et le shipper sur la même machine. Je pense qu'il aurait été intéressant de distribuer la charge sur plusieurs machines (notamment pour ElasticSearch). Je vais essayer de voir si je ne pourrais pas récupérer quelques machines pour aller un peu plus loin dans mes tests. Mais en l'état, je pense que je vais arrêter mes tests pour l'instant.

mardi 20 mars 2012

Quelques tests du mod_gearman avec nagios

J'ai dernièrement travaillé sur la mise en place d'une nouvelle infra nagios se basant sur une Redhat EL5.5 à la place de ma zone Solaris (youpi ! enfin du Linux sur notre infra !). A cette occasion, j'ai voulu voir ce que donné le mod gearman. Avant de le mettre en production, je l'ai activé sur mon poste (Debian/Kubuntu). J'en décris ici les principales étapes ainsi que les résultats de quelques tests.

Compilation

Ici, rien de très compliqué, il faut récupérer la dernière version (1.2.4 au moment de la rédaction de l'article mais la 1.2.6 est sortie entre temps) à l'adresse suivante : http://labs.consol.de/wp-content/uploads/2010/09/mod_gearman-1.2.4.tar.gz
Avant compilation, installons quelques pré-requis :
apt-get install gearman libgearman-dev
Vient ensuite le temps de la compilation :
# Décompression
tar xfv mod_gearman-1.2.4.tar.gz && cd mod_gearman-1.2.4
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
make
make install

Intégration de gearman dans nagios

De là, vous devriez obtenir un binaire /usr/lib/mod_gearman/mod_gearman.o que vous pouvez maintenant référencer de la manière suivante dans votre fichier /etc/nagios3/nagios.cfg :
broker_module=/usr/lib/mod_gearman/mod_gearman.o localhostgroups=local-server server=localhost:4730 key=Found@nor1g1nalK3y$ eventhandler=yes services=yes hosts=yes
Ici, il faut surtout noter les points suivants :
  • L'option localhostgroups donne le nom des groupes de machine sur lesquelles nous ne déléguerons pas les appels. Il est de bon goût d'y mettre les machines de votre infra nagios afin d'être sûr de détecter les problèmes sur vos services gearman ;
  • L'option server donne l'adresse d'écoute du démon gearman ;
  • L'option key permettant de gérer le chiffrement des communications entre les process gearman ;
  • Enfin les options eventhandler=yes services=yes hosts=yes permettant d'indiquer ce que nous pouvons faire faire à nos workers gearman.
Il  ne nous reste plus qu'à lancer les workers gearman et faire recharger la configuration à notre moteur nagios :
/etc/init.d/mod_gearman_worker start
Starting mod_gearman_worker...OK
/etc/init.d/nagios3 reload
 * Reloading nagios3 monitoring daemon configuration files nagios3

Lancement d'un petit bench

Maintenant que notre conf est prête, voyons l'impact de gearman sur le fonctionnement de notre moteur nagios. Tout d'abord, un test en désactivant gearman pour avoir une idée de la capacité native de notre moteur nagios.

A propos de la machine et du bench

Rien de particulier à signaler, il s'agit d'un processeur quadri-coeur (AMD Phenom(tm) II X4 965) avec 4 Go de mémoire.
Concernant la conf nagios du bench, elle consiste à créer des fichiers de configuration contenant les éléments suivants :
define host{
        use                     generic-host
        process_perf_data       0
        host_name               @HOST@
        alias                   @HOST@
        address                 127.0.0.1
        }

define service{
        use                             generic-service         ; Name of service template to use
        host_name                       @HOST@
        service_description             dummy1
        check_interval                  1
        check_command                   return-ok
}
[...]

Sans mod_gearman

Voici grosso modo les temps forts au niveau du changement de conf :
Heurenb machinesnb servicesinterval
20h4540056005min
20h5540056001min
21h2560084001min
21h40800112001min

Tout ceci a entraîné le comportement suivant au niveau de la machine de bench :
  • Latence du moteur nagios :
  •  Consommation CPU de la machine

La consommation avoisine en pointe les 92 % avec une moyenne - pour la fin du test - dans les 75%. La latence se situe dans les 500ms en fin de test.

Avec mod_gearman

Passons maintenant la même configuration avec gearman actif. Tout d'abord les évènements du bench :
Heurenb machinesnb servicesinterval
22h0040056001min
22h2060084001min
22h40800112001min
23h021000140001min
23h221200168001min

Et maintenant le comportement du serveur pendant cette même période :
  • Latence du moteur nagios :
  • Consommation CPU :

Non seulement la consommation CPU n'a jamais dépassé 37 % en pointe (on est plutôt à 25% de moyenne) mais en plus, on a pu faire 50 % de tests en plus sans impact particulier au niveau de la machine et en gardant une latence inférieur à 400ms.

Pour conclure ...

Comme on peut le voir, l'utilisation de gearman fait grandement baisser la consommation CPU de notre serveur. D'autant plus que gearman offre également la capacité de distribuer nos surveillances sur plusieurs machines différentes. Vous pouvez également déporter la génération des graphiques sur une autre machine (à l'aide du mode gearman de PNP4Nagios par exemple).

Si vous combinez tout ceci,  nous sommes face à un outil apportant une très grande souplesse à ce vieux moteur nagios. Non seulement vous réduisez votre consommation CPU mais tout en vous laissant la possibilité de distribuer très facilement vos éléments de surveillance/métrologie en fonction de vos besoins.

Pour aller plus loin, je vous conseille de faire un tour sur le site de gearman qui présente pas mal de possibilité d'architecture.