Avec l’évolution des applications modernes répondant à des besoins croissants en traitement et en récupération de données en temps réel, la scalabilité évolue également. Un moteur de recherche et d’analyse distribué open-source tel qu’Elasticsearch est très efficace pour traiter des données en grands ensembles et pour des requêtes à haute vélocité. Cependant, le processus de mise à l’échelle efficace d’Elasticsearch peut être nuancé, car il nécessite une compréhension adéquate de son architecture et des compromis de performance.
La nature distribuée d’Elasticsearch lui permet de s’étendre horizontalement, mais cela introduit également plus de complexités dans la répartition des données et le traitement des requêtes. L’un des défis théoriques associés à la mise à l’échelle d’Elasticsearch est sa nature intrinsèquement distribuée. Dans la plupart des cas pratiques, les lectures sur un nœud autonome seront toujours plus performantes que les lectures dans un cluster sharded. Cela est dû au fait que, dans un cluster sharded, la propriété des données est répartie sur plusieurs nœuds. Cela signifie que chaque requête peut devoir envoyer plusieurs demandes à différents nœuds, agréger les résultats au nœud de coordination et renvoyer le résultat. Ce surcroît de charge réseau entraînera facilement une augmentation de la latence par rapport à une architecture à nœud unique où l’accès aux données est direct.
À cet égard, les clusters sharded sont fondamentaux pour mettre à l’échelle Elasticsearch à de grands ensembles de données, à un trafic élevé et à un indexage quasi en temps réel. Connaître le juste équilibre entre la répartition des données sur les nœuds et le maintien d’une faible latence des requêtes est essentiel pour obtenir des performances optimales. En outre, l’article couvre les aspects théoriques de la scalabilité d’Elasticsearch, les stratégies pratiques d’optimisation des performances des clusters et les leçons tirées des expériences de déploiement dans le monde réel.
Chez Swoo, notre application de diffusion en direct et de jeu, Elasticsearch était l’épine dorsale de toutes les recherches, et tout fonctionnait parfaitement lorsque notre base d’utilisateurs augmentait. Dès que le nombre d’utilisateurs simultanés a dépassé les 150 000, la page de recherche a commencé à dysfonctionner de temps en temps, et il était évident qu’il y avait un goulot d’étranglement dans le cluster Elasticsearch. Cela est rapidement devenu inacceptable pour un environnement de jeu en direct et nous a amenés à effectuer une série d’optimisations, qui ont finalement stabilisé à la fois nos expériences de recherche et de page d’accueil.
Comprendre l’architecture Elasticsearch pour la scalabilité
Elasticsearch prend en charge nativement une architecture distribuée, rendant le système hautement scalable mais, en même temps, plus complexe par rapport aux solutions traditionnelles à nœud unique. Elasticsearch divise les données en index, chaque index étant lui-même divisé en shards. Le shard est l’unité de base de stockage de données et d’indexation dans Elasticsearch, car le système distribue et parallélise les opérations de recherche sur plusieurs nœuds du cluster.
Un cluster typique contiendrait plusieurs nœuds de données hébergeant un sous-ensemble des données qui exécutent des requêtes de recherche. Par défaut, Elasticsearch peut distribuer automatiquement les données entre les nœuds, de sorte que chaque nœud n’exécute qu’une partie de la charge de requête. De cette manière, Elasticsearch s’étend horizontalement : il traite de plus en plus de données et répond à un nombre croissant de requêtes en ajoutant simplement des nœuds.
Ce compromis entre la scalabilité et les performances des requêtes est, bien sûr, l’une des choses les plus importantes à considérer lors de la conception de clusters Elasticsearch, en particulier pour les applications nécessitant un haut débit d’écriture combiné à une faible latence de lecture. Un tel défi demande en effet une configuration soigneuse du cluster ainsi qu’un mélange de techniques d’optimisation.
En essence, notre cluster Elasticsearch disposait de quelques nœuds de données pour le cas de Swoo et de trois nœuds maîtres dédiés. Chaque nœud fonctionnait sur un CPU 8 cœurs avec 16 Go de RAM, principalement axé sur l’indexation en temps réel et les recherches instantanées des événements de jeu en cours. Étant donné que nous travaillons à une concurrence élevée, nous devons allouer une bande passante réseau vraiment substantielle pour garantir une latence minimale entre les nœuds.
Planifier votre stratégie de mise à l’échelle
En d’autres termes, mettre à l’échelle Elasticsearch efficacement nécessite l’analyse des métriques de performance actuelles, l’identification des goulots d’étranglement et la définition d’objectifs clairs en matière de scalabilité. Par exemple, il est important de surveiller la latence des requêtes, le débit et la santé du cluster afin de comprendre les limites de votre cluster. Vous pourrez établir une feuille de route pour l’optimisation en identifiant les shards actifs, les pics de CPU et les problèmes de mémoire.
Une autre activité importante qui nécessite une attention particulière lors de la mise à l’échelle d’Elasticsearch est la planification de la capacité. Estimer l’utilisation du disque, le modèle de trafic et les exigences de conservation des données garantira que votre cluster est correctement dimensionné. En général, l’évolutivité horizontale (ajout de nœuds au cluster) est généralement la meilleure approche pour augmenter le volume de données et de trafic. Dans ce cas, cependant, l’évolutivité verticale – mise à niveau des ressources des nœuds individuels – peut être efficace.
Nos projections indiquaient une croissance des utilisateurs actifs d’environ 10 à 15 % d’un mois à l’autre, chaque utilisateur générant un volume considérable de données d’événements au cours de l’utilisation du jeu. Sur la base de ces projections, nous nous attendions à ce que notre cluster maintienne une montée en charge saine des requêtes simultanées avec une augmentation du volume de documents indexés. Par conséquent, nous avons analysé si l’évolutivité horizontale en ajoutant plus de nœuds de données ou l’évolutivité verticale en mettant à niveau nos nœuds actuels serait plus adaptée à cette augmentation.
Techniques de mise à l’échelle essentielles
L’optimisation d’Elasticsearch impliquera un certain nombre de stratégies, chacune ciblant différents aspects du système. Parmi celles-ci, les techniques les plus efficaces comprennent l’optimisation des données d’ingestion, la gestion des shards et l’optimisation de l’utilisation de la mémoire.
Les principaux domaines d’intérêt seront l’ingestion de données. Elasticsearch prend en charge nativement l’indexation en masse, ce qui signifie que vous pouvez envoyer de très gros lots de documents en une seule requête. Cela réduit la surcharge et accélère généralement le processus d’indexation. Deuxièmement, ajuster l’intervalle de rafraîchissement peut faire toute la différence lors de l’ingestion rapide de données. Vous remplacez l’intervalle de rafraîchissement par défaut d’une seconde par une valeur plus élevée, disons dix secondes, car cela réduira la pression des rafraîchissements trop fréquents sur votre cluster, et vos écritures seront plus rapides.
D’autres raisons clés qui constituent la fonctionnalité d’évolutivité d’Elasticsearch incluent la gestion des shards. Bien qu’Elasticsearch soit capable de se dimensionner horizontalement grâce au sharding, un dimensionnement inapproprié des shards entraîne en réalité une dégradation des performances. Un nombre de shards trop élevé ou trop faible entraîne une diminution de la vitesse d’indexation et/ou des performances des requêtes. Le secret réside dans l’équilibre pour une performance optimale dans Elasticsearch.
Bien sûr, la gestion de la mémoire est un autre facteur très important dans l’évolutivité d’Elasticsearch. Vous réduisez certainement la consommation de ressources et améliorez les performances de vos requêtes en optimisant la taille du tas JVM, en configurant le cache des données de champ et en activant le cache des requêtes. Une utilisation appropriée de la mémoire et des paramètres de mise en cache adéquats peuvent éviter les erreurs de mémoire insuffisante et minimiser la surcharge de collecte des ordures.
Une bonne partie de la tension d’Elasticsearch était due à l’ingestion continue de données de jeux en temps réel. Nous avons optimisé les pipelines d’ingestion en regroupant les documents via l’API en blocs. En période de charge maximale, nous pouvions augmenter davantage les tailles des blocs et prolonger la période de rafraîchissement pour trouver un compromis adéquat entre l’indexation quasi en temps réel et la stabilité générale du cluster.
Solutions de mise à l’échelle avancées
Lorsque l’échelle devient immense, Elasticsearch nécessite des techniques plus avancées pour être performant. Parmi celles-ci, l’optimisation des requêtes se démarque. Vous pouvez également réduire considérablement la latence des requêtes en rédigeant des requêtes efficaces qui minimisent le nombre de shards impliqués dans la recherche. Par exemple, vous pouvez effectuer un routage personnalisé pour diriger les requêtes vers des shards spécifiques en utilisant une clé, telle que l’ID client ou la catégorie de produit. Cela permet à Elasticsearch d’éviter de rechercher tous les shards ; ainsi, le temps et les ressources utilisés sont réduits.
L’ILM, ou Gestion du cycle de vie de l’index, est une autre fonctionnalité impressionnante pour peaufiner Elasticsearch à mesure que vos données vieillissent. Vous pourrez déplacer les données plus anciennes vers un stockage plus lent et moins cher tout en conservant les plus pertinentes sur un stockage plus rapide et plus accessible en mettant en place une architecture chaude-tiède-froide. Cela maintient les performances du cluster excellentes à mesure que le cluster se développe.
Les derniers sujets de discussion concernant la scalabilité d’Elasticsearch sont les considérations matérielles. À mesure que votre cluster se développe, vous voudrez vous assurer que le matériel est correctement provisionné pour la charge accrue. Cela signifierait s’assurer que les nœuds disposent du CPU, de la mémoire et des E/S disque appropriés pour fonctionner efficacement. Les SSD ou les disques NVMe amélioreront considérablement les performances, notamment pour les opérations d’indexation et de recherche, qui nécessitent des vitesses d’accès aux données élevées.
Une des leçons apprises à la dure était que assigner uniquement le nombre de shards par défaut aux nouveaux indices nous poserait problème avec le phénomène de hot spotting. Nous avons également trouvé un point idéal où aucun shard n’était vraiment surchargé avec la majorité des mises à jour en temps réel provenant de notre plateforme de jeux vidéo par des indices à forte écriture redistribués à travers de multiples shards plus petits, en ajustant les répliques en conséquence.
Perceptions Théoriques et Compromis d’Optimisation
En plus des optimisations pratiques mentionnées ci-dessus, il y a quelques considérations théoriques intéressantes en matière de mise à l’échelle d’Elasticsearch. Une clé de compréhension concerne les compromis entre scalabilité et performance des requêtes au sein d’un système distribué. En particulier, il est noté que bien que les clusters shardés soient évolutifs horizontalement, ils augmentent la charge des requêtes car les résultats de plusieurs nœuds doivent être combinés. Cela contraste avec un seul nœud où les données résident sur la machine locale, et les requêtes peuvent être exécutées sans avoir à « parler » à d’autres nœuds. Comprendre ce compromis est important si l’on conçoit un cluster Elasticsearch qui doit équilibrer performance et scalabilité.
Un autre aspect plus théorique de la mise à l’échelle d’Elasticsearch est le concept de localisation des données. Vous pouvez exécuter des requêtes uniquement contre le nœud local hébergeant les données de shard pertinentes en utilisant le paramètre de requête preference=local
. Cela limite la communication entre les nœuds et réduit la latence des requêtes. Cela peut réduire les défis liés à la réplication des données et à l’équilibrage de la charge. L’algorithme de sélection de réplique adaptative Elasticsearch tente d’optimiser l’exécution des requêtes en choisissant le meilleur nœud de réplique dans les conditions actuelles. Cependant, cela ne garantit pas forcément l’exécution la plus efficace d’une requête.
La première vague d’échecs que nous avons rencontrée dans notre environnement est liée à une forte pression sur le tas JVM. Les serveurs Elasticsearch fonctionnaient initialement avec des allocations de tas minimales, ce qui entraînait des cycles de collecte de déchets assez fréquents sous une charge de requêtes élevée. Nous avons résolu ce problème en ajustant la JVM, en particulier en alignant la taille minimale et maximale du tas à 8 Go, ce qui a donné à Elasticsearch suffisamment d’espace pour traiter les requêtes sans surcharger le tas.
Erreurs Courantes et Solutions
Bien sûr, l’extension d’Elasticsearch n’est pas exempte de défis non plus. Parmi les erreurs courantes à éviter figurent une mauvaise dimension des fragments, un manque de surveillance, une dépendance excessive à la mise en cache, et le non-usage d’une gestion de cycle de vie d’index appropriée. Ces éléments permettent d’économiser beaucoup de temps et de ressources s’ils sont diagnostiqués tôt par un réglage proactif de la configuration.
Un des principaux écueils était de ne pas ajuster les paramètres par défaut d’Elasticsearch, tant en ce qui concerne l’allocation de mémoire que la gestion des fragments. Les valeurs par défaut fonctionnaient bien dans des conditions de trafic modéré mais échouaient sous un trafic de pointe. Notre solution était multi-niveaux : elle a révisé l’allocation du tas, la réplication d’index chauds et la mise en cache à court terme pour les requêtes répétées. Dans l’ensemble, cela a empêché les échecs répétés à travers l’ensemble du cluster et a considérablement réduit les délais d’attente.
Guide d’Implémentation en Conditions Réelles
Étendre Elasticsearch impliquera la planification, les tests, le déploiement et la maintenance par la suite. Il est donc logique de suivre de bonnes pratiques, des modèles de configuration et de tester rigoureusement votre cluster avant de déployer de nouveaux changements en production pour garantir une extension sans problème vers un cluster stable sur le long terme.
- Peaufiner les paramètres de la JVM. Nous avons configuré à 8 Go à la fois Xms et Xmx sur chaque serveur Elasticsearch, en trouvant un équilibre entre la mémoire système disponible et les besoins en mémoire heap.
- Optimisation de la distribution des shards. Les grands index ont été divisés en shards de taille plus petite pour éviter les points chauds et l’expansion des répliques pour les index les plus actifs. Cela assurait une distribution uniforme du trafic de requêtes à travers le cluster.
- Activer le caching à courte durée de vie. Nous avons appliqué une fenêtre de mise en cache d’1 seconde sur les requêtes statiques fréquemment utilisées sur la page d’accueil, et nous avons remarqué que cela réduisait considérablement la charge sur Elasticsearch pour les demandes répétitives sans perdre de réactivité en temps réel.
- Surveillance et itération. Nous avons utilisé Kibana, avec certains tableaux de bord personnalisés pour une observation en temps réel de la santé des shards, des performances de la JVM et des latences des requêtes. Sur la base de ces métriques, des ajustements fins ont été effectués en continu.
Plans à venir ou Expansion de la pile technologique
De plus, pour la croissance, nous aimerions explorer la gestion d’un cycle de vie d’index chaud-chaud-froid en déplaçant les données moins fréquemment consultées vers des nœuds moins chers tout en conservant du matériel de premier choix pour l’indexation et les requêtes en temps réel. Nous examinons des solutions de surveillance avancées et une détection d’anomalies pilotée par l’IA pour nous assurer que les pics ou les ralentissements dans les requêtes inhabituelles sont anticipés bien à l’avance avant d’impact sur l’expérience utilisateur.
Conclusion
L’évolutivité d’Elasticsearch nécessite une compréhension de l’architecture, une planification minutieuse et la mise en place des meilleures pratiques. Bien qu’Elasticsearch évolue horizontalement grâce au sharding, il présente plusieurs défis qui doivent être maîtrisés pour des performances optimales. La haute évolutivité et les performances d’un cluster Elasticsearch peuvent être assurées par une ingestion de données appropriée, une gestion des shards, une utilisation de la mémoire et une optimisation des requêtes adéquates.
Alors que la migration vers Elasticsearch était également nécessaire pour Solr dans notre cas, sans aucun doute, en plus des questions purement techniques, une contribution importante a été apportée concernant la compréhension des difficultés théoriques qui sont en réalité cachées sous-jacentes dans les Systèmes Distribués. Ce type d’ajustement prudent et de résolution de problèmes créatifs pourrait permettre de grandir considérablement – un cluster Elasticsearch unique multivendeur – censé recevoir des millions de requêtes par jour en améliorant ses performances de requête avec des temps de réponse considérablement réduits. Les éléments théoriques et pratiques se fondent ensemble lors de la mise à l’échelle de votre déploiement Elasticsearch pour garantir le succès à long terme.
Source:
https://dzone.com/articles/how-to-scale-elasticsearch-to-solve-scalability-issues