Dépannage des goulots d'étranglement courants de performance dans Elasticsearch
Elasticsearch est un moteur de recherche et d'analyse distribué puissant, réputé pour sa rapidité et son évolutivité. Cependant, comme tout système complexe, il peut rencontrer des problèmes de performance qui affectent l'indexation, les requêtes et la réactivité globale du cluster. Identifier et résoudre ces goulots d'étranglement est crucial pour maintenir un déploiement Elasticsearch sain et efficace. Cet article fournit un guide pratique pour dépanner les problèmes de performance courants, offrant des solutions exploitables pour diagnostiquer et corriger les indexations lentes, les requêtes retardées et la contention des ressources.
Comprendre et aborder les goulots d'étranglement de performance nécessite une approche systématique. Nous allons explorer les coupables courants, allant des limitations matérielles et des erreurs de configuration à la modélisation de données inefficace et aux modèles de requêtes inappropriés. En analysant systématiquement le comportement de votre cluster et en appliquant des optimisations ciblées, vous pouvez améliorer considérablement les performances d'Elasticsearch et garantir une expérience utilisateur fluide.
Diagnostic des problèmes de performance
Avant de plonger dans des solutions spécifiques, il est essentiel de disposer d'outils et de méthodes pour diagnostiquer les problèmes de performance. Elasticsearch fournit plusieurs API et métriques inestimables pour ce processus.
Outils et métriques clés :
- API de santé du cluster (
_cluster/health) : Fournit un aperçu de l'état du cluster (vert, jaune, rouge), du nombre de nœuds, de shards et des tâches en attente. Un nombre élevé de tâches en attente peut indiquer des problèmes d'indexation ou de récupération. - API de statistiques des nœuds (
_nodes/stats) : Offre des statistiques détaillées pour chaque nœud, y compris l'utilisation du CPU, la mémoire, les E/S disque, le trafic réseau et l'utilisation du tas (heap) JVM. Ceci est essentiel pour identifier les nœuds limités par les ressources. - API de statistiques des index (
_stats) : Fournit des statistiques pour les index individuels, tels que les taux d'indexation, les taux de recherche et l'utilisation du cache. Cela aide à identifier les index problématiques. - Journal des ralentissements (Slow Log) : Elasticsearch peut journaliser les opérations d'indexation et de recherche lentes. La configuration et l'analyse de ces journaux sont l'un des moyens les plus efficaces pour identifier les opérations inefficaces.
- Journal des ralentissements d'indexation : Seuil configurable pour la durée maximale qu'une opération d'indexation doit prendre avant d'être journalisée. Emplacement :
config/elasticsearch.yml. - Journal des ralentissements de recherche : Seuil configurable pour la durée maximale qu'une requête de recherche doit prendre avant d'être journalisée. Emplacement :
config/elasticsearch.yml.
- Journal des ralentissements d'indexation : Seuil configurable pour la durée maximale qu'une opération d'indexation doit prendre avant d'être journalisée. Emplacement :
- Outils de surveillance : Des solutions telles que l'interface utilisateur de surveillance de Kibana, Prometheus avec l'exportateur Elasticsearch, ou les outils APM commerciaux fournissent des tableaux de bord et des données historiques pour une analyse plus approfondie.
Goulots d'étranglement courants et solutions
1. Indexation lente
L'indexation lente peut être causée par divers facteurs, notamment la latence réseau, les goulots d'étranglement des E/S disque, des ressources insuffisantes, un mappage inefficace ou une utilisation sous-optimale de l'API Bulk.
Causes et solutions :
-
Saturation des E/S disque : Elasticsearch dépend fortement des E/S disque rapides pour l'indexation. Les SSD sont fortement recommandés.
- Diagnostic : Surveillez les IOPS et le débit de lecture/écriture du disque à l'aide de
_nodes/statsou des outils au niveau du système d'exploitation. Recherchez des profondeurs de file d'attente élevées. - Solution : Mettez à niveau vers un stockage plus rapide (SSD), répartissez les shards sur plus de nœuds ou optimisez votre stratégie de shard pour réduire les E/S par nœud.
- Diagnostic : Surveillez les IOPS et le débit de lecture/écriture du disque à l'aide de
-
Pression sur le tas (Heap) JVM : Si le tas JVM est constamment sous pression, le ramasse-miettes (garbage collection) peut devenir un goulot d'étranglement important, ralentissant toutes les opérations, y compris l'indexation.
- Diagnostic : Surveillez l'utilisation du tas JVM dans Kibana Monitoring ou
_nodes/stats. Une utilisation élevée du tas et des pauses de ramasse-miettes fréquentes et longues sont des signaux d'alarme. - Solution : Augmentez la taille du tas JVM (mais pas au-delà de 50 % de la RAM système et pas plus de 30,5 Go), optimisez les mappages pour réduire la taille des documents ou ajoutez plus de nœuds pour répartir la charge.
- Diagnostic : Surveillez l'utilisation du tas JVM dans Kibana Monitoring ou
-
Mappage inefficace : Des mappages trop complexes, un mappage dynamique créant de nombreux nouveaux champs ou des types de données incorrects peuvent augmenter la surcharge d'indexation.
- Diagnostic : Analysez les mappages d'index (API
_mapping). Recherchez des objets imbriqués, un grand nombre de champs ou des champs indexés inutilement. - Solution : Définissez des mappages explicites avec des types de données appropriés. Utilisez
dynamic: falseoudynamic: strictlorsque cela est applicable. Évitez les structures profondément imbriquées si ce n'est pas essentiel.
- Diagnostic : Analysez les mappages d'index (API
-
Latence réseau : Une latence élevée entre les nœuds ou entre les clients et le cluster peut ralentir les requêtes d'indexation en masse (bulk).
- Diagnostic : Mesurez la latence réseau entre vos clients/nœuds. Analysez les temps de réponse de l'API Bulk.
- Solution : Assurez-vous que les nœuds sont géographiquement proches des clients, optimisez l'infrastructure réseau ou augmentez
indices.requests.cache.expiresi vous utilisez la mise en cache.
-
Utilisation sous-optimale de l'API Bulk : L'envoi de requêtes individuelles au lieu d'utiliser des requêtes en masse, ou l'envoi de requêtes en masse excessivement grandes/petites, peut être inefficace.
- Diagnostic : Surveillez le débit de votre indexation en masse. Analysez la taille de vos requêtes en masse.
- Solution : Utilisez l'API Bulk pour toutes les opérations d'indexation. Expérimentez avec la taille du lot (généralement 5 à 15 Mo par requête bulk est un bon point de départ) pour trouver l'équilibre optimal entre débit et latence. Assurez-vous que vos requêtes en masse sont correctement regroupées.
-
Durabilité du Translog : Le paramètre
index.translog.durabilitycontrôle la fréquence à laquelle le journal des transactions est vidé sur le disque.request(par défaut) est plus sûr mais peut avoir un impact sur les performances par rapport àasync.- Diagnostic : Il s'agit d'un paramètre de configuration.
- Solution : Pour un débit d'indexation maximal, envisagez une durabilité
async. Cependant, sachez que cela augmente le risque de perte de données en cas de crash du nœud entre les vidages (flushes).
2. Requêtes lentes
La performance des requêtes est influencée par la taille des shards, la complexité de la requête, la mise en cache et l'efficacité de la structure de données sous-jacente.
Causes et solutions :
-
Shards trop grands : Les shards trop volumineux peuvent ralentir les requêtes car Elasticsearch doit rechercher dans plus de données et fusionner les résultats provenant de plus de segments.
- Diagnostic : Vérifiez la taille des shards à l'aide de
_cat/shardsou_all/settings?pretty. - Solution : Visez des tailles de shard comprises entre 10 Go et 50 Go. Envisagez de réindexer les données dans un nouvel index avec des shards plus petits ou d'utiliser la gestion du cycle de vie des index (ILM) pour gérer la taille des shards au fil du temps.
- Diagnostic : Vérifiez la taille des shards à l'aide de
-
Trop de shards : Avoir un nombre excessif de petits shards peut entraîner une surcharge importante pour le cluster, en particulier lors des recherches. Chaque shard nécessite des ressources pour sa gestion.
- Diagnostic : Comptez le nombre total de shards par nœud et par index à l'aide de
_cat/shards. - Solution : Consolidez les index si possible. Optimisez votre modèle de données pour réduire le nombre d'index et donc le nombre total de shards. Pour les données de séries temporelles, ILM peut aider à gérer le nombre de shards.
- Diagnostic : Comptez le nombre total de shards par nœud et par index à l'aide de
-
Requêtes inefficaces : Les requêtes complexes, celles impliquant des scripts lourds, des recherches par joker (wildcard) au début des termes ou des expressions régulières peuvent être très gourmandes en ressources.
- Diagnostic : Utilisez l'API Profile (
_search?profile=true) pour analyser le temps d'exécution de la requête et identifier les parties lentes. Analysez les journaux des ralentissements. - Solution : Simplifiez les requêtes. Évitez les jokers de début et les expressions régulières coûteuses. Utilisez des requêtes
termau lieu dematchpour les correspondances exactes lorsque cela est possible. Envisagez d'utiliser les suggestionssearch_as_you_typeoucompletionpour les suggestions de pré-remplissage. Optimisez les clauses de filtre (utilisez le contextefilterau lieu du contextequerypour les requêtes sans score).
- Diagnostic : Utilisez l'API Profile (
-
Manque de mise en cache : Une mise en cache insuffisante ou inefficace peut entraîner des calculs et des récupérations de données répétés.
- Diagnostic : Surveillez les taux de réussite du cache pour le cache de requête et le cache de requête (request cache) à l'aide de
_nodes/stats/indices/query_cacheet_nodes/stats/indices/request_cache. - Solution : Assurez-vous qu'une mise en cache appropriée est activée. Le cache de filtre (faisant partie du cache de requête) est particulièrement important pour les requêtes de filtre répétées. Pour les requêtes identiques fréquemment exécutées, envisagez d'activer le cache de requête.
- Diagnostic : Surveillez les taux de réussite du cache pour le cache de requête et le cache de requête (request cache) à l'aide de
-
Surcharge de fusion des segments : Elasticsearch fusionne les petits segments en segments plus grands en arrière-plan. Ce processus consomme des ressources E/S et CPU, ce qui peut parfois avoir un impact sur les performances des requêtes en temps réel.
- Diagnostic : Surveillez le nombre de segments par shard à l'aide de
_cat/segments. - Solution : Assurez-vous que
index.merge.scheduler.max_thread_countest correctement configuré. Pour le réindexage en masse, envisagez de désactiver temporairement la fusion des shards ou d'ajuster les paramètres de fusion.
- Diagnostic : Surveillez le nombre de segments par shard à l'aide de
3. Contention des ressources (CPU, Mémoire, Réseau)
La contention des ressources est une catégorie large qui peut se manifester par une dégradation des performances d'indexation et de requête.
Causes et solutions :
-
Surcharge de CPU : Une utilisation élevée du CPU peut être causée par des requêtes complexes, des agrégations intensives, trop d'opérations d'indexation ou un ramasse-miettes excessif.
- Diagnostic : Surveillez l'utilisation du CPU par nœud (
_nodes/stats). Identifiez les opérations qui consomment le plus de CPU (par exemple, recherche, indexation, GC JVM). - Solution : Optimisez les requêtes et les agrégations. Répartissez la charge sur plus de nœuds. Réduisez le taux d'indexation s'il submerge le CPU. Assurez des paramètres de tas JVM adéquats pour minimiser la surcharge du GC.
- Diagnostic : Surveillez l'utilisation du CPU par nœud (
-
Problèmes de mémoire (Tas JVM et mémoire système) : Un tas JVM insuffisant entraîne un GC fréquent. L'épuisement de la mémoire système peut provoquer un échange (swapping), réduisant considérablement les performances.
- Diagnostic : Surveillez l'utilisation du tas JVM et la mémoire système globale (RAM, swap) sur chaque nœud.
- Solution : Allouez un tas JVM suffisant (par exemple, 50 % de la RAM système, jusqu'à 30,5 Go). Évitez le swapping en vous assurant qu'il y a suffisamment de mémoire système libre. Envisagez d'ajouter plus de nœuds ou d'utiliser des nœuds dédiés pour des rôles spécifiques (maître, données, ingestion).
-
Goulots d'étranglement réseau : Un trafic réseau élevé peut ralentir la communication inter-nœuds, la réplication et les requêtes des clients.
- Diagnostic : Surveillez l'utilisation de la bande passante réseau et la latence entre les nœuds et les clients.
- Solution : Optimisez l'infrastructure réseau. Réduisez les transferts de données inutiles. Assurez une allocation des shards et des paramètres de réplication optimaux.
-
Saturation des E/S disque : Comme mentionné pour l'indexation, cela affecte également les performances des requêtes lors de la lecture des données depuis le disque.
- Diagnostic : Surveillez les métriques des E/S disque.
- Solution : Mettez à niveau vers un stockage plus rapide, répartissez les données sur plus de nœuds ou optimisez les requêtes pour réduire la quantité de données lues.
Bonnes pratiques pour l'optimisation des performances
- Surveillez en continu : L'optimisation des performances est un processus continu. Surveillez régulièrement l'état de santé de votre cluster et l'utilisation des ressources.
- Optimisez les mappages : Définissez des mappages explicites et efficaces adaptés à vos données. Évitez les champs ou l'indexation inutiles.
- Stratégie de Shard : Visez des tailles de shard optimales (10-50 Go) et évitez d'avoir trop ou trop peu de shards.
- Utilisez l'API Bulk : Utilisez toujours l'API Bulk pour les opérations d'indexation et de recherche multiple.
- Ajustez le tas JVM : Allouez un tas suffisant, mais ne surallouez pas. Évitez le swapping.
- Comprenez la performance des requêtes : Profilez les requêtes, simplifiez-les et utilisez le contexte de filtre.
- Tirez parti de la mise en cache : Assurez-vous que les caches de requête et de requête sont utilisés efficacement.
- Matériel : Utilisez des SSD pour le stockage et assurez un CPU et une RAM adéquats.
- Nœuds dédiés : Envisagez d'utiliser des nœuds dédiés pour les rôles maître, données et ingestion afin d'isoler les charges de travail.
- Gestion du cycle de vie des index (ILM) : Pour les données de séries temporelles, ILM est essentiel pour gérer les index, faire pivoter les shards et finalement supprimer les anciennes données, ce qui aide à contrôler le nombre et la taille des shards.
Conclusion
Le dépannage des goulots d'étranglement de performance d'Elasticsearch nécessite une combinaison de compréhension de l'architecture du système, d'utilisation des outils de diagnostic et d'application systématique d'optimisations. En vous concentrant sur les domaines courants comme le débit d'indexation, la latence des requêtes et la contention des ressources, et en suivant les meilleures pratiques, vous pouvez maintenir un cluster Elasticsearch performant et fiable. N'oubliez pas que chaque cluster est unique, et que la surveillance continue et l'ajustement itératif sont essentiels pour atteindre des performances optimales.