Elasticsearch In Production - Meilleures pratiques de déploiement

Elasticsearch est un moteur de recherche hautement optimisé pour l'analyse de données moderne.

Elasticsearch est un incroyable moteur de recherche et d'analyse en temps réel. Il est construit sur Apache Lucene. Il est distribué, RESTful, facile à utiliser et hautement disponible. Les cas d'utilisation d'Elasticsearch incluent la recherche, la surveillance des transactions et la détection des erreurs, la découverte de contenu, l'analyse de journaux, la recherche floue, l'agrégation de données d'événements, la visualisation de données. Elasticsearch et le reste de l'Elastic Stack se sont révélés extrêmement polyvalents et, comme vous pouvez le constater ci-dessus, il existe de nombreuses façons d'intégrer Elasticsearch à ce que votre produit fournit aujourd'hui et d'ajouter des informations supplémentaires.

Chez Botmetric, nous l'utilisons beaucoup pour la recherche et l'analyse, nous indexons environ un milliard de documents par jour et nous utilisons des agrégations très complexes pour la visualisation de données en temps réel.

Cela dit, le démarrage d’une application ou son exécution en production et sa maintenance sont totalement différents. Cet article couvre bon nombre de ces facteurs à partir d'expériences réelles et constitue l'élément de base commun à prendre en compte pour l'exécution d'Elasticsearch en production.

Mémoire:

Elasticsearch et Lucene sont écrits en Java, ce qui signifie que vous devez rechercher les statistiques relatives aux espaces et à la JVM. Plus le nombre de segments de mémoire disponibles par Elasticsearch est élevé, plus la mémoire utilisée par le filtre et les autres capacités de cache pour augmenter les performances des requêtes est élevée. Mais notez que trop de tas peut vous soumettre à de longues pauses de récupération de place. Ne définissez pas Xmx au-dessus de la valeur limite utilisée par la machine virtuelle Java pour les pointeurs d’objets compressés (oops compressés); la coupure exacte varie mais se situe autour de 32 Go.

Un problème courant est la configuration d’un tas trop volumineux. Vous avez une machine de 64 Go - et vous voulez bien donner à Elasticsearch toutes les 64 Go de mémoire. Plus c'est mieux! Heap est définitivement important pour Elasticsearch. Il est utilisé par de nombreuses structures de données en mémoire pour un fonctionnement rapide. Cela dit, il existe un autre utilisateur important de mémoire qui est hors du tas: le cache de fichiers du système d'exploitation.

Lucene est conçu pour tirer parti du système d'exploitation sous-jacent pour la mise en cache des structures de données en mémoire. Les segments de Lucene sont stockés dans des fichiers individuels. Comme les segments sont immuables, ces fichiers ne changent jamais. Cela les rend très conviviaux pour le cache et le système d’exploitation sous-jacent gardera volontiers les segments chauds en mémoire pour un accès plus rapide. Ces segments incluent à la fois l'index inversé (pour la recherche en texte intégral) et les valeurs doc (pour les agrégations). Les performances de Lucene reposent sur cette interaction avec le système d’exploitation. Mais si vous donnez toute la mémoire disponible au segment de mémoire d’Elasticsearch, il ne restera plus aucune trace du cache de fichiers du système d’exploitation. Cela peut sérieusement affecter la performance. La recommandation standard est de donner 50% de la mémoire disponible à la pile Elasticsearch, tout en laissant les 50% restants libres. Il ne sera pas utilisé non utilisé; Lucene se fera un plaisir de consommer tout ce qui reste pour le cache de fichiers. Le tas Elasticsearch peut être configuré de différentes manières,

exportation ES_HEAP_SIZE = 10g

ou

ES_JAVA_OPTS = "- Xms10g -Xmx10g" ./bin/elasticsearch

CPU:

Elasticsearch prend en charge les agrégations et les requêtes filtrées. L'exécution de requêtes filtrées complexes, l'indexation intensive, la percolation et les requêtes sur les index nécessitent un processeur important, il est donc essentiel de choisir celui qui convient. Vous devez comprendre les spécifications de la CPU et leur comportement avec Java lorsque les requêtes s'exécutent sur la machine virtuelle Java.

Chaque pool exécute un certain nombre de threads, configurables, et comporte une file d'attente. Changer cela n'est pas recommandé, sauf si vous avez des exigences très spécifiques car Elasticsearch attribue les cœurs de manière dynamique.

Types de pool de threads:

Elasticsearch a 3 types de pools de threads.

  1. Mis en cache: le pool de threads mis en cache est un pool de threads non lié qui générera un thread s'il existe des demandes en attente. Ce pool de threads est utilisé pour empêcher le blocage ou le rejet des demandes soumises à ce pool. Les threads non utilisés dans ce pool de threads seront terminés après l'expiration d'un maintien en vie (cinq minutes par défaut). Le pool de threads mis en cache est réservé au pool de threads générique.
  2. Corrigé: le pool de threads fixe contient une taille fixe de threads pour gérer les demandes avec une file d'attente (éventuellement liée) pour les demandes en attente ne disposant d'aucun thread pour les traiter. Le paramètre size contrôle le nombre de threads et prend par défaut le nombre de cœurs multiplié par 5.
  3. Mise à l'échelle: le pool de threads de mise à l'échelle contient un nombre dynamique de threads. Ce nombre est proportionnel à la charge de travail et varie entre 1 et la valeur du paramètre size.

Elasticsearch divise l'utilisation de la CPU en pools de threads de différents types:

  • générique: pour les opérations standard telles que la découverte et le type de pool de threads est mis en cache.
  • index: pour les opérations d'index / delete. Le type de pool de threads est corrigé.
  • search: pour les opérations de comptage / recherche. Le type de pool de threads est corrigé.
  • get: pour obtenir des opérations. Le type de pool de threads est corrigé.
  • bulk: pour les opérations en bloc telles que l'indexation en masse. Le type de pool de threads est corrigé. La meilleure configuration de documents en vrac dépend de la configuration du cluster. Vous pouvez l'identifier en testant plusieurs valeurs.
  • percolate: pour la percolation. Le type de pool de threads est corrigé.
  • refresh: pour les opérations de rafraîchissement. Le type de pool de threads est en cours de dimensionnement.

Vous pouvez modifier un pool de threads spécifique en définissant ses paramètres spécifiques au type.

En savoir plus https://www.elastic.co/guide/fr/elasticsearch/reference/2.2/modules-threadpool.html#types

Taille de l'éclat:

Le fragment est l'unité dans laquelle Elasticsearch distribue des données au sein du cluster. La vitesse à laquelle Elasticsearch peut déplacer des fragments lors du rééquilibrage des données, par ex. suivant une défaillance, dépendra de la taille et du nombre de fragments, ainsi que des performances du réseau et du disque.

Dans Elasticsearch, chaque requête est exécutée dans un seul thread par fragment. Plusieurs fragments peuvent cependant être traités en parallèle, de même que plusieurs requêtes et agrégations sur le même fragment.

Cela signifie que la latence minimale des requêtes, lorsqu'aucune mise en cache n'est impliquée, dépendra des données, du type de requête, ainsi que de la taille du fragment. Interroger un grand nombre de petits fragments accélérera le traitement, mais comme de nombreuses autres tâches doivent être mises en file d'attente et traitées en séquence, il ne sera pas forcément plus rapide que d'interroger un plus petit nombre de fragments plus grands. Avoir beaucoup de petits fragments peut également réduire le débit de la requête s'il y a plusieurs requêtes simultanées.

Chaque fragment contient des données qui doivent être conservées en mémoire et utilise beaucoup d’espace. Cela inclut les structures de données contenant des informations au niveau de la partition et également au niveau du segment afin de définir l'emplacement des données sur le disque. La taille de ces structures de données n'est pas fixe et varie en fonction du cas d'utilisation. Une caractéristique importante de la surcharge liée au segment est toutefois qu’elle n’est pas strictement proportionnelle à la taille du segment. Cela signifie que les segments plus importants entraînent moins de temps système par volume de données que les segments plus petits. La différence peut être substantielle. Choisir le bon nombre de fragments est compliqué, car vous ne savez jamais combien de documents vous obtiendrez avant de commencer. Avoir beaucoup de fragments peut être à la fois bon et terrible pour un cluster. La gestion des index et des partitions peut surcharger le nœud maître, ce qui peut ne plus répondre, ce qui entraîne un comportement étrange et désagréable. Allouez à vos nœuds maîtres suffisamment de ressources pour faire face à la taille du cluster.

Le problème, c'est que le nombre de fragments est immuable et qu'il est défini lors de la création de l'index. Une fois l’index créé, le seul moyen de modifier le nombre de fragments consiste à supprimer vos index, à les recréer et à les réindexer.

Réplication

Elasticsearch prend en charge la réplication, les données sont répliquées entre les nœuds de données afin qu'une perte de nœud n'entraîne pas de perte de données. Par défaut, le facteur de réplication est 1, mais en fonction des exigences de votre produit, il peut être augmenté. Plus vos répliques et vos données seront résistantes aux sinistres. Un autre avantage du nombre de répliques réside dans le fait que chaque nœud contient un fragment de réplica, ce qui améliore les performances des requêtes car les répliques sont également utilisées pour les requêtes.

La formule de réplication utilisée par Elasticsearch pour la cohérence est,

(primary + number_of_replicas) / 2 + 1

Optimiser l'allocation

En fonction des exigences du produit, nous pouvons classer les données en chaud et en froid. Il est possible d’attribuer plus de nœuds de données aux index auxquels on accède plus souvent que d’autres, tandis que moins de ressources sont allouées aux index moins fréquemment utilisés. Cette stratégie est particulièrement utile pour stocker des données de séries chronologiques telles que les journaux d'application (par exemple: ELK).

Cela peut être réalisé en exécutant une tâche cron qui déplace les index vers différents nœuds à intervalles réguliers.

Le noeud chaud est un type de noeud de données qui effectue toute l'indexation au sein du cluster. Ils détiennent également les indices les plus récents, ceux-ci ayant généralement tendance à être interrogés. L'indexation étant une opération intensive du processeur et des E / S, ces serveurs doivent être puissants et protégés par un stockage SSD attaché. Nous vous recommandons d'exécuter un minimum de 3 nœuds chauds pour une haute disponibilité. En fonction de la quantité de données récentes que vous souhaitez collecter et interroger, vous devrez peut-être augmenter ce nombre pour atteindre vos objectifs de performance.

Le nœud Warm est un type de nœud de données conçu pour gérer une grande quantité d'index en lecture seule qui sont moins susceptibles d'être interrogés fréquemment. Comme ces index sont en lecture seule, les nœuds chauds ont tendance à utiliser de gros disques attachés (généralement des disques en rotation) au lieu de disques SSD. Comme pour le nœud chaud, nous recommandons un minimum de 3 nœuds chauds pour la haute disponibilité. Et comme auparavant, il convient de noter que de plus grandes quantités de données peuvent nécessiter des nœuds supplémentaires pour répondre aux exigences de performances. Notez également que les configurations de processeur et de mémoire devront souvent refléter celles de vos nœuds actifs. Cela ne peut être déterminé qu'en testant avec des requêtes similaires à celles que vous rencontriez en situation de production.

Pour plus de détails sur les nœuds chauds et chauds, reportez-vous ici.

Une autre stratégie que vous pouvez adapter consiste à archiver les index sur s3 et à restaurer lorsque vous avez besoin de données provenant de ces index. Vous pouvez en savoir plus à ce sujet à partir d'ici.

Topologie de nœud:

Les nœuds Elasticsearch peuvent être divisés en trois catégories: nœud principal, nœud de données et nœud client.

  1. Nœud maître: Le nœud maître peut être petit s'il ne s'agit pas d'un nœud de données, car il ne stocke aucun index / fragment. Sa responsabilité est de stocker l'état détaillé du cluster et les données d'aide et les autres nœuds dans la recherche de méta-données index / shards. Elasticsearch doit avoir plusieurs nœuds principaux pour éviter les problèmes de fractionnement du cerveau.
  2. Nœud de données: le nœud de données est chargé de stocker / interroger les données d'index réelles.
  3. Noeud client: Le noeud client est utilisé comme proxy pour l'indexation et la recherche. Ceci est fortement recommandé si les agrégations sont fortement utilisées. Ce sont des nœuds ElasticSearch spéciaux qui ne sont ni des données ni des maîtres éligibles. Les nœuds clients sont sensibles aux clusters et peuvent donc agir en tant qu'équilibreurs de charge intelligents. Vous pouvez envoyer vos requêtes aux noeuds client, qui peuvent alors se charger de la tâche onéreuse de rassembler les réponses aux résultats de la requête de chacun des noeuds de données.

ajoutez ces paramètres au fichier elasticsearch.yml pour les nœuds respectifs.

Noeud maître: node.master: true node.data:false
Noeud de données: node.master: false node.data:true
Noeud client: node.master: false node.data:false

Des conseils de dépannage:

Les performances d'Elasticsearch dépendent fortement de la machine sur laquelle il est installé. L'UC, l'utilisation de la mémoire et l'E / S du disque sont des mesures de base du système d'exploitation pour chaque nœud Elasticsearch. Il est recommandé d'examiner les métriques JVM (Java Virtual Machine) lorsque l'utilisation de l'UC augmente. Dans l'exemple suivant, le pic était dû à une activité de récupération de place supérieure.

  1. Pression de segmentation: une pression de mémoire élevée affecte les performances du cluster de deux manières: lorsque la pression de mémoire atteint 75% et plus, il reste moins de mémoire disponible, et votre cluster doit également utiliser certaines ressources de son processeur pour récupérer de la mémoire via le garbage collection. Ces cycles de processeur ne sont pas disponibles pour traiter les demandes des utilisateurs lorsque le nettoyage de la mémoire est activé. En conséquence, les temps de réponse aux demandes des utilisateurs augmentent à mesure que le système devient de plus en plus contraint par les ressources. Si la pression de la mémoire continue d'augmenter et atteint près de 100%, une forme de récupération des déchets bien plus agressive est utilisée, ce qui affectera considérablement les temps de réponse des grappes. La mesure des temps de réponse de l'index montre qu'une pression mémoire élevée entraîne un impact significatif sur les performances.
  2. Augmentation de la mémoire non-tas de la machine virtuelle Java, réduisant la mémoire destinée au cache de page et pouvant entraîner une moisson au niveau du MOO au niveau du noyau.
  3. Évitez les problèmes de fracture du cerveau. La scission du cerveau est un scénario dans lequel le cluster se scinde. Par exemple, vous avez un cluster à 6 nœuds. 2 nœuds se déconnectent du cluster, mais ils peuvent toujours se voir. Ces 2 nœuds créent alors un autre cluster. Ils éliront même un nouveau maître entre eux. Nous avons maintenant deux clusters du même nom, l’un à 4 nœuds et l’autre à 2 nœuds. Chacun a aussi un noeud principal. C'est ce que l'on appelle un problème de split-brain avec des clusters ES. Pour éviter cela, définissez le paramètre ES discovery.zen.minimum_master_nodes sur la moitié du nombre de nœuds + 1.
  4. Etant donné que Elasticsearch utilise beaucoup de périphériques de stockage, la surveillance des E / S de disque garantit la satisfaction de ce besoin fondamental. La réduction des E / S du disque a de nombreuses raisons. Elle est considérée comme une mesure clé pour la prévision de nombreux types de problèmes. C'est une bonne mesure pour vérifier l'efficacité de l'indexation et des performances de requête. L'analyse des opérations de lecture et d'écriture indique directement ce dont le système a le plus besoin dans un cas d'utilisation spécifique. Les paramètres du système d'exploitation pour les E / S de disque constituent une base pour toutes les autres optimisations. Le réglage des E / S de disque peut éviter des problèmes potentiels. Si les E / S de disque ne suffisent toujours pas, il convient d'évaluer les mesures correctives, telles que l'optimisation du nombre de fragments et de leur taille, la fusion, le remplacement des disques lents, le déplacement sur des disques SSD ou l'ajout de nœuds supplémentaires en fonction des circonstances. goulots d'étranglement.
  5. Pour les applications qui reposent sur la recherche, l'expérience utilisateur est fortement corrélée à la latence des demandes de recherche. Plusieurs facteurs peuvent affecter les performances des requêtes, tels que les requêtes construites, les problèmes de cluster Elasticsearch mal configurés, les problèmes de mémoire JVM et de récupération de place, les E / S de disque, etc. La latence des requêtes est la métrique qui a un impact direct sur les utilisateurs. Assurez-vous donc de placer des alertes dessus.
  6. La plupart des filtres dans Elasticsearch sont mis en cache par défaut. Cela signifie que lors de la première exécution d'une requête filtrée, Elasticsearch trouvera les documents correspondant au filtre et construira une structure appelée «jeu de bits» à l'aide de ces informations. Les données stockées dans le bitet contiennent un identifiant de document et indiquent si un document donné correspond au filtre. Les exécutions ultérieures de requêtes ayant le même filtre réutiliseront les informations stockées dans le jeu de bits, accélérant ainsi l'exécution de la requête en enregistrant les opérations d'E / S et les cycles de processeur. L'utilisation du filtre dans la requête est recommandée. Pour plus de détails, voir ici.
  7. Les temps d'actualisation et de fusion sont étroitement liés aux performances d'indexation et ont également une incidence sur les performances globales du cluster. La durée d'actualisation augmente avec le nombre d'opérations de fichier pour l'index Lucene (fragment).
  8. L'activation de la journalisation lente des requêtes vous aidera à identifier les requêtes lentes et ce qui peut être fait pour les améliorer, particulièrement utile pour les requêtes génériques.
  9. Augmentez la taille ulimit pour autoriser le nombre maximal de fichiers.
  10. Les performances d'ElasticSearch peuvent en pâtir lorsque le système d'exploitation décide de remplacer la mémoire d'application inutilisée. Désactivez la permutation en définissant les paramètres de niveau du système d'exploitation ou définissez les éléments suivants dans ElasticSearch config bootstrap.mlockall: true
  11. Désactiver la suppression de tous les index par requête générique. Pour vous assurer que personne ne lance une opération DELETE sur tous les index (* ou _all), définissez action.destructive_requires_name sur true.

Avant de terminer, voici la liste des URL utiles pour consulter les métriques.

  • / _cluster / health? pretty: pour l'indicateur de santé du cluster.
  • / _status? pretty: Pour toutes les informations sur tous les index.
  • / _nodes? pretty: Pour toutes les informations sur les nœuds.
  • / _cat / master? pretty: Pour le noeud principal.
  • / _stats? pretty: Pour l’attribution de tessons, index stats.
  • / _nodes / stats? pretty: pour les statistiques de nœud individuel, cela inclut les statistiques jvm, http, io pour le nœud.

L'agrégation de mesures d'Elasticsearch est prise en charge par la plupart des outils de surveillance du système tels que Datadog, TICK. L'utilisation de tels outils est recommandée et la création d'un entonnoir est fortement recommandée pour la surveillance continue d'Elasticsearch.

Conclusion:

Elasticsearch est un moteur de recherche et d'analyse en texte intégral distribué, qui permet à plusieurs locataires d'effectuer une recherche dans l'ensemble de leurs ensembles de données, quelle que soit leur taille, à des vitesses sans précédent. En plus de ses capacités de recherche en texte intégral, ElasticSearch sert également de système d’analyse et de base de données distribuée. ElasticSearch a d'excellents paramètres par défaut pour commencer. Mais une fois la phase d’expérimentation initiale terminée, vous devez prendre le temps de peaufiner les réglages pour répondre à vos besoins. Il est recommandé de revoir votre configuration ultérieurement, ainsi que la documentation officielle, pour vous assurer que votre cluster est configuré pour répondre à vos besoins.