ElasticSearch 5
Fin 2016, Elastic a sorti une nouvelle version d’ElasticSearch, la 5.0.
Elastic a profité de la montée de version pour choisir un nouveau logo, de nouveaux noms (“ELK” doit désormais être appelé “Elastic Stack”) et une uniformisation des numéros de version pour tout l’écosystème qui gravite autour, notamment :
Les raisons de l’adoption d’ElasticSearch depuis la première version sont la simplicité de mise en place initiale (dev friendly), la vitesse et la scalabilité, et Elastic a développé cette nouvelle version dans cette optique.
Disclaimer : Cette nouvelle version apporte énormément de changements. Dans cet article, je ne vais évoquer qu’une partie de ces changements, si vous souhaitez une liste plus complète, vous pourrez la trouver ici :
Nouveaux types de données
ElasticSearch se base désormais sur Apache Lucene en version 6, qui apporte de nouveaux types de données.
Concernant les chaînes de caractères, adieu le type string
, il faut désormais choisir entre les types keyword
(non analysé) ou text
(analysé). Le type string
est désormais un alias de keyword
.
Les types numériques ne sont pas en reste : Avant, les nombres étaient stockés en interne de la même manière que les chaînes de caractères. A présent ils sont stockés dans une nouvelle structure appelée BKD-Tree (voir ce papier pour plus d’informations), ce qui permet de gagner en performance, ainsi qu’en occupation mémoire, que ce soit sur le disque ou en RAM. De nouveaux types font leur apparition pour les nombres flottants :
- “
scaled float
” : nombre flottant stocké dans un “long”, avec un facteur de scalabilité fixe - “
half float
” : flottant sur 16 bits (vs 32 bits pour un float)
Les types géographiques ainsi que les adresses IP bénéficient également de cette amélioration de structure et de performance ; de plus, cette nouvelle version prend en charge l’IPv6 et des plages d’adresses IP.
A noter, les nombres stockés dans des BKD-Tree sont en constant scoring, si vous souhaitez qu’ils continuent à participer au scoring, il vous faudra les indexer sous forme de keyword
.
Amélioration des performances
Au niveau performances, la nouvelle gestion des types numériques couplée à un DSL plus rapide permet des gains de performance appréciables, autant en indexation qu’en recherche. Sur un projet sur lequel j’ai pu mettre en place ElasticSearch 5, l’indexation a été 4 fois plus rapide, et la recherche 1,5 fois plus rapide.
Elastic a mis à disposition son outil de bench nommé Rally, et publie régulièrement les résultats des benchs, version par version.
Exemple de résultat publié sur l’indexation d’un gros volume de données, à savoir les informations sur les taxis de la ville de New York, en comparant les versions 1.7.6, 2.4.5 ainsi que 5.4.0 :
Format des fichiers
Au niveau du format des fichiers, la migration de ElasticSearch 1 à ElasticSearch 2 avait été assez difficile pour les anciens index, avec beaucoup de changements impactants, tels que l’interdiction des points dans le nom des champs. La migration de ElasticSearch2 à ElasticSearch 5 est beaucoup plus facile, avec notamment la possiblité de charger directement dans ElasticSearch 5 un index ElasticSearch 2. En revanche, impossible de charger un index ElasticSearch 1 dans ElasticSearch 5.
Pour faciliter la migration des index depuis les versions antérieures, ElasticSearch a mis à disposition un plugin “elasticsearch-migration”, qui va indiquer les fonctionalités deprecated dans la version cible, à modifier avant de pouvoir migrer l’index. Ce plugin existe en 2 versions : 1 version pour ElasticSearch 1->2, et 1 version pour ElasticSearch 2->5. Voici les liens :
Au niveau noms de fichiers sur disque, jusqu’à présent, les répertoires sur le disque portaient le même nom que l’index qu’ils contenaient. A partir d’ElasticSearch 5.0, chaque répertoire d’index porte le nom d’un UUID auto-généré. Ce changement est motivé par des améliorations dans la résilience des données et du merge des données après un crash de nœud.
Améliorations sécurité & résilience des données
En plus d’une meilleure gestion de reprise des données suite à un crash serveur, ElasticSearch s’est doté de nouvelles fonctionnalités afin d’assurer une expérience optimale.
BootStrap checks
Des contrôles au démarrage ont été mis en place afin de s’assurer que chaque nœud s’exécute dans les meilleurs conditions possibles. Ces contrôles sont désactivables en conditions de dev (ip bindée à localhost), mais dès qu’une IP autre que localhost est définie, ElasticSearch considère que le nœud s’exécute en conditions de production, et ces contrôles s’appliquent sans dérogation possible. Ces contrôles incluent :
- Vérification de la HeapSize (Xms & Xms doivent être égaux pour éviter les fluctuations mémoire)
- Nombre de file descriptors que le nœud est autorisé à ouvrir (minimum : 65536)
- Nombre maximum de threads autorisés
- Vérification des conflits de classes dans les classpath (plus possible de démarrer un nœud embedded si le classpath n’est pas propre)
- Etc. (voir liste complète des Bootstrap checks)
Safe Guards
Afin d’éviter de se tirer une balle dans le pied, certains garde-fous sont mis en place (désactivables), tels que :
- Limitation du nombre de champs dans un index (défaut : 1000)
- Profondeur maximum d’objets imbriqués (défaut : 20)
- Nombre de champs nested dans un index (défaut : 50)
Evolution au niveau des plugins
Gros changement dans le cycle de vie de plugins : ceux-ci doivent à présent suivre les versions de la stack Elastic (1 plugin = 1 sous-version). Autre gros changement, les “site plugins” sont supprimés. A présent, il faut développer 1 plugin sous ElasticSearch et 1 plugin sous Kibana.
plugin Delete By Query
Extraite sous forme de plugin dans la version 2 d’ElasticSearch, cette fonctionalité réintègre le cœur d’ElasticSearch 5.
Evolution au niveau des API
En plus de l’API Delete By Query qui fait son grand retour, de nouvelles API font leur apparition :
“Reindex API” apparue sous forme expérimentale en version 2.3, cette API à présent finalisée a pour but de recopier tout ou partie des documents d’un ou plusieurs index dans un index cible. Un filtrage est possible par index, par type de document, par requête ainsi que par langage de script. Cette API peut même être utilisée pour réindexer les données d’un cluster distant. Attention, cette API ne recopie que les documents, charge à vous de préparer les settings d’index ainsi que les mappings au préalable.
“Shrink API” est une toute nouvelle API, qui permet de prendre un index existant, et d’en créer une copie avec moins de primary shards. Utile par exemple pour des index temporels tels que des index Logstash quotidiens, les plus anciens index - les moins sollicités - peuvent être “shrinkés” afin d’occuper moins d’espace disque.
“Rollover API” va permettre de définir un alias d’index glissant suivant certaines conditions, afin de répartir les données. Par exemple, on va pouvoir choisir de générer un nouvel index physique tous les 10.000 documents, ou alors de générer un nouvel index tous les 7 jours. Les noms des index créés possèderont un numéro incrémental. Ex : logs-00001, logs-00002, etc.
De nouvelles options communes font également leur apparition sur l’ensemble des API REST :
human=true : va convertir les valeurs numériques en valeurs compréhensibles par des humains, par ex.
"exists_time" : "1h"
pour rendre compréhensible l’expression"exists_time_in_millis" : 3600000
refresh=wait_for : Plutôt que de forcer le refresh de l’index après insertion/mise à jour d’un document, cette option va demander à ElasticSearch de ne rendre la main qu’une fois le refresh suivant effectué, et lorsque le document est effectivement disponible. Très utile par exemple pour un site web ajax qui crée un document et qui grâce à cette option, va rafraichir sa liste de documents en étant sûr que le nouveau document est bien présent.
Unités : on va pouvoir utiliser des unités pour les milliers, millions, etc. grâce aux suffixes kb, mb, gb, tb, pb (ou pour les autres unités : k, m, g, t, p). De même pour les distances dans les requêtes géographiques, on va pouvoir utiliser les unités anglaises (in, ft, ya, mi) ainsi que les unités du système international (mm, cm, m, km). Concernant les dates, on va pouvoir utiliser des opérations (“date math”), telles que “now+2h”. Ces “date math” sont également utilisables pour les noms d’index. Ex :
monindex-${now-1d}
.
X-Pack : nouveautés
X-Pack est la suite d’outils complémentaires, soumise à souscription, permettant de gérer la sécurité, le monitoring, l’alerting et le reporting de la stack Elastic.
Chose intéressante : “monitoring”, qui remplace l’outil précédemment nommé Marvel, solution de surveillance du cluster, est désormais utilisable via une licence “basic” gratuite (qu’il faut tout de même renouveller chaque année). Le monitoring concerne à présent à la fois ElasticSearch, Kibana et Logstash.
Un nouvel outil a rejoint la suite X-Pack en 5.4 : nommé “Machine Learning”, il s’agit de la première mouture de l’intégration de Prelert (http://info.prelert.com/) directement dans la stack Elastic, et qui permet une détection d’anomalies sur l’ensemble des séries temporelles des données contenues dans votre cluster ElasticSearch.
Conclusion
La montée de version vers ElasticSearch 5 peut représenter un défi de taille, surtout sur un gros projet. Nous avons sauté le pas pour un projet qui se basait sur ElasticSearch 1.6. Nous avons procédé en plusieurs étapes ; d’abord en adaptant le code à la syntaxe ElasticSearch 2, puis en adaptant le code à la syntaxe ElasticSearch 5. Nous avons dû réécrire l’intégralité des mappings du projet, et mettre à jour la plupart des requêtes, ce qui n’a pas été une mince affaire ! Cependant, l’effort a été récompensé par les gains de performance non négligeables qui apportent un réel confort à l’utilisation de notre application.
Les améliorations de monitoring et les nouvelles API nous ont également permis de mieux gérer nos index volumineux.