Stratégie de dimensionnement des shards Elasticsearch : Trouver l'équilibre optimal
Elasticsearch, un moteur puissant de recherche et d'analyse distribué, doit une grande partie de son évolutivité et de ses performances à son architecture sous-jacente, en particulier au concept de shards (fragments). Les shards sont essentiellement des index Lucene indépendants qui contiennent un sous-ensemble de vos données. Comprendre et optimiser leur taille n'est pas seulement une bonne pratique ; c'est un facteur critique qui a un impact direct sur la performance, la stabilité et l'efficacité des coûts de votre cluster.
Cet article vous guidera à travers les complexités du dimensionnement des shards Elasticsearch. Nous explorerons pourquoi le dimensionnement des shards est si crucial, les divers facteurs qui influencent la taille optimale et les compromis impliqués dans le fait d'avoir trop ou trop peu de shards. À la fin, vous disposerez d'une stratégie pratique et d'informations exploitables pour déterminer la bonne configuration de shards pour votre cas d'utilisation spécifique, vous aidant à éviter les pièges courants et à atteindre un cluster Elasticsearch équilibré, performant et évolutif.
Comprendre les shards Elasticsearch
Avant de plonger dans le dimensionnement, récapitulons brièvement ce que sont les shards et comment ils fonctionnent au sein d'un cluster Elasticsearch.
Qu'est-ce qu'un Shard ?
Dans Elasticsearch, un index est un regroupement logique de données. Pour distribuer ces données et permettre le traitement parallèle, un index est divisé en un ou plusieurs shards. Chaque shard est un index Lucene autonome. Lorsque vous créez un index, vous définissez le nombre de shards primaires qu'il aura.
Pour une haute disponibilité et une évolutivité en lecture, Elasticsearch vous permet également de spécifier des shards de réplique. Un shard de réplique est une copie exacte d'un shard primaire. Si le nœud d'un shard primaire tombe en panne, une réplique peut être promue pour prendre sa place, assurant la disponibilité des données et évitant la perte de données. Les répliques servent également les requêtes de recherche, distribuant la charge de lecture.
Comment fonctionnent les Shards
Lorsque vous indexez un document, Elasticsearch détermine à quel shard primaire il appartient en fonction d'un algorithme de routage (par défaut, basé sur l'ID du document). Ce document est ensuite stocké sur ce shard primaire spécifique et ses shards de réplique correspondants. Lorsque vous effectuez une recherche, la requête est envoyée à tous les shards pertinents, qui traitent leur portion des données en parallèle. Les résultats sont ensuite agrégés et renvoyés au client. Ce traitement parallèle est ce qui confère à Elasticsearch son immense vitesse et son évolutivité.
Pourquoi le dimensionnement des Shards est important
Le dimensionnement optimal des shards est un élément fondamental pour un cluster Elasticsearch sain. Un dimensionnement incorrect peut entraîner une myriade de problèmes, allant de performances de requête lentes à un gaspillage coûteux de ressources et à des scénarios de récupération instables.
Performances
- Vitesse des requêtes : Un shard bien dimensionné peut traiter les requêtes efficacement. Des shards trop petits entraînent plus de surcharge de coordination ; des shards trop grands signifient des temps de recherche individuels de shard plus longs.
- Débit d'indexation : De même, la performance d'indexation peut être impactée. Si les shards sont trop petits, la surcharge de gestion de nombreux shards peut ralentir les écritures. Si les shards sont trop grands, la performance individuelle du shard peut devenir un goulot d'étranglement.
Utilisation des ressources
Chaque shard consomme des ressources sur le nœud où il réside, y compris le CPU, la mémoire (tas JVM) et les E/S disque. Un dimensionnement approprié garantit que vos nœuds sont utilisés efficacement sans être surchargés ou sous-utilisés.
Évolutivité (Scalability)
Les shards sont les unités de distribution dans Elasticsearch. Pour évoluer horizontalement, vous ajoutez plus de nœuds, et Elasticsearch rééquilibre les shards entre eux. Si les shards sont trop grands, le rééquilibrage prend plus de temps et nécessite plus de bande passante réseau. Si vous avez trop peu de shards, vous pourriez atteindre un plafond d'évolutivité prématurément, car vous ne pouvez pas distribuer la charge de travail au-delà du nombre de shards primaires.
Récupération et Stabilité
- Pannes de nœud : Lorsqu'un nœud tombe en panne, Elasticsearch doit réallouer ses shards primaires (en promouvant des répliques) et recréer les répliques perdues. Le temps que cela prend est directement proportionnel à la taille et au nombre de shards impliqués.
- Récupération du Cluster : Les grands shards prennent plus de temps à récupérer et à répliquer, augmentant la fenêtre de vulnérabilité pendant les pannes de nœud ou les redémarrages de cluster.
Facteurs influençant le dimensionnement des Shards
Déterminer la bonne taille de shard n'est pas une solution unique. Cela dépend de plusieurs facteurs interdépendants spécifiques à votre cas d'utilisation et à votre infrastructure.
- Volume et Croissance des données : Votre taille de données actuelle et le taux de croissance projeté sont fondamentaux. Un index statique de 100 Go aura des exigences différentes d'un index roulant qui augmente de 1 To par jour.
- Taille du Document et Complexité du Schéma : Les index avec de nombreux champs ou de très grands documents pourraient bénéficier de shards plus petits, car le traitement de chaque document nécessite plus de ressources.
- Modèles de Requêtes :
- Axé sur la recherche (Search-heavy) : Si votre cluster est principalement utilisé pour la recherche, vous pourriez donner la priorité à un nombre plus élevé de shards plus petits pour maximiser la parallélisation et minimiser les temps de recherche individuels de shard.
- Axé sur l'analyse (Analytics-heavy, agrégations) : Les grandes agrégations pourraient être plus performantes avec des shards plus grands, car la surcharge de la combinaison des résultats provenant de nombreux petits shards peut devenir significative.
- Taux d'Indexation : Des taux d'indexation élevés pourraient bénéficier de plus de shards pour distribuer la charge d'écriture, mais un nombre excessif peut introduire une surcharge.
- Spécifications des Nœuds : Le CPU, la RAM (taille du tas JVM) et le type de disque (SSD vs. HDD) de vos nœuds de données sont cruciaux. Les nœuds plus puissants peuvent gérer plus de shards ou des shards plus grands.
- Topologie du Cluster : Le nombre total de nœuds de données disponibles pour distribuer les shards a un impact direct sur le nombre réalisable de shards.
Les Compromis : Trop ou Trop Peu de Shards
Trouver l'équilibre optimal signifie comprendre les conséquences des deux extrêmes.
Conséquences d'un nombre trop élevé de Shards
Bien que plus de shards semblent offrir plus de parallélisme, il y a un point de rendements décroissants :
- Surcharge Plus Élevée : Chaque shard consomme du CPU et de la mémoire (tas JVM) pour ses métadonnées, ses fichiers ouverts, ses fusions de segments, etc. Trop de shards sur un nœud entraînent une consommation globale plus élevée de ressources pour la gestion des shards eux-mêmes, laissant moins de ressources pour le traitement réel des données.
- Conseil : Une règle empirique courante est de n'autoriser pas plus de 1 Mo de tas par shard. Pour un tas de 30 Go, cela représente 30 000 shards au total sur tous les nœuds, y compris les répliques.
- Récupération Plus Lente : Lors des pannes de nœud ou du rééquilibrage, la gestion et le déplacement de nombreux petits shards prennent plus de temps et d'E/S réseau qu'un nombre plus réduit de shards plus grands.
- Augmentation de la Contention des Ressources : Lorsque de nombreux shards effectuent activement des opérations (par exemple, fusion de segments, réponse aux requêtes) sur le même nœud, ils se disputent le CPU, la mémoire et les E/S disque, ce qui entraîne une performance globale plus lente.
- « Shard Bloat » (Gonflement des Shards) : Un cluster avec de nombreux petits shards, majoritairement vides, est inefficace. Il consomme des ressources pour la gestion sans bénéfices de données proportionnels.
Conséquences d'un nombre trop faible de Shards
Réciproquement, avoir trop peu de shards présente également des défis importants :
- Parallélisation Limitée : Si un index n'a que quelques grands shards, les requêtes de recherche ne peuvent pas exploiter toute la puissance de traitement de votre cluster, car la charge de travail ne peut pas être distribuée sur de nombreux nœuds/cœurs.
- Points Chauds (Hot Spots) : Un grand shard sur un seul nœud peut devenir un « point chaud » s'il reçoit une quantité disproportionnée de requêtes de lecture ou d'écriture, conduisant à une saturation des ressources sur ce nœud spécifique.
- Difficulté à Évoluer (Scaling Out) : Si votre index n'a, par exemple, que 5 shards primaires, vous ne pouvez distribuer efficacement cet index que sur un maximum de 5 nœuds de données. L'ajout de nœuds supplémentaires n'aidera pas les performances de cet index particulier si tous les shards sont déjà sur des nœuds différents.
- Rééquilibrage Plus Lent : Le déplacement d'un seul très grand shard à travers le réseau pendant le rééquilibrage est une opération chronophage et gourmande en E/S, pouvant potentiellement impacter la stabilité du cluster.
- Temps de Récupération Plus Longs : Un seul grand shard qui doit être récupéré ou copié peut prolonger considérablement le temps de récupération du cluster après une panne.
Recommandations Générales et Meilleures Pratiques
Bien qu'aucune règle unique ne s'applique à tous, quelques lignes directrices largement acceptées constituent un bon point de départ.
Taille de Shard Cible
La recommandation la plus souvent citée pour une taille de shard individuelle (après indexation et fusions potentielles) se situe entre 10 Go et 50 Go. Certaines sources étendent cela jusqu'à 100 Go pour des scénarios spécifiques (par exemple, données de séries chronologiques avec principalement des écritures en ajout seul et moins de requêtes complexes). Cette plage offre généralement un bon équilibre entre la gérabilité, la vitesse de récupération et l'utilisation efficace des ressources.
- Pourquoi cette plage ? :
- Récupération : Les shards dans cette plage peuvent récupérer relativement rapidement après une panne de nœud.
- Performance : Ils sont assez grands pour minimiser la surcharge, mais assez petits pour permettre un traitement efficace et des fusions rapides.
- Évolutivité : Permet une distribution flexible sur les nœuds.
Shards par Nœud
Évitez d'avoir un nombre excessif de shards sur un seul nœud. Une heuristique courante suggère de maintenir le nombre total de shards (primaires + répliques) sur un nœud à moins de 10 à 20 shards par Go de tas JVM alloué à ce nœud. Par exemple, un nœud avec un tas de 30 Go ne devrait idéalement pas héberger plus de 300 à 600 shards. Cela aide à prévenir une utilisation excessive de la mémoire pour les métadonnées des shards et réduit la contention.
Architecture Hot-Warm-Cold et Dimensionnement des Shards
Dans une architecture Hot-Warm-Cold (HWC), le dimensionnement des shards peut varier :
- Tier Hot (Chaud) : Nœuds de données recevant des écritures actives et fréquemment interrogés. Ici, vous pourriez opter pour légèrement plus de shards ou des shards plus petits afin de maximiser le débit d'indexation et le parallélisme des requêtes.
- Tier Warm/Cold (Tiède/Froid) : Nœuds détenant des données plus anciennes, moins fréquemment consultées. Ces shards sont généralement plus grands, car l'indexation s'est arrêtée et les fusions sont complètes. Des shards plus grands (jusqu'à 100 Go et plus) peuvent être acceptables ici pour réduire le nombre total de shards et la surcharge associée, en particulier sur un stockage optimisé pour les coûts.
Répliques
Utilisez toujours des répliques ! Un minimum d'une réplique par shard primaire (soit 2 copies totales de vos données) est crucial pour la haute disponibilité. Les répliques augmentent également la capacité de lecture en distribuant les requêtes de recherche. Le nombre optimal de répliques dépend de vos exigences de disponibilité et de votre charge de requêtes.
Stratégie Pratique pour Déterminer la Taille des Shards
Voici une approche étape par étape pour dériver une stratégie initiale de dimensionnement des shards, suivie d'un processus d'affinement itératif.
Étape 1 : Estimer le Volume Total et la Croissance des Données
Projetez la quantité de données que votre index (ou vos index roulants quotidiens/mensuels) contiendra sur son cycle de vie. Tenez compte de la taille moyenne des documents.
- Exemple : Vous prévoyez d'ingérer 100 Go de données par jour et de les conserver pendant 30 jours. Vos données actives totales seront d'environ 3 To (
100 Go/jour * 30 jours).
Étape 2 : Déterminer la Taille Cible des Shards
Commencez par la recommandation générale de 30 Go à 50 Go par shard primaire. Ajustez en fonction de votre cas d'utilisation :
- Shards plus petits (par exemple, 10-20 Go) : Si vous avez un débit de requêtes très élevé, des agrégations complexes sur de grands documents, ou des données changeant très fréquemment.
-
Shards plus grands (par exemple, 50-100 Go) : Si vous avez principalement des données de séries chronologiques, des index en ajout seul (append-only), ou des requêtes moins fréquentes et plus simples.
-
Exemple (suite de l'Étape 1) : Visons une taille moyenne de shard primaire de 50 Go.
Étape 3 : Calculer le Nombre Initial de Shards Primaires
Divisez votre volume total de données estimé par la taille cible de shard.
Nombre de Shards Primaires = (Volume Total de Données) / (Taille Cible de Shard)
- Exemple :
3000 Go / 50 Go = 60 shards primaires.
Étape 4 : Tenir Compte des Ressources des Nœuds et de la Taille du Tas
Déterminez combien de shards primaires et de répliques votre cluster peut héberger confortablement, en respectant la règle des shards par Go de tas.
- Tas par Nœud : Supposons que vous ayez des nœuds de données avec un tas JVM de 30 Go chacun.
- Nombre Maximal de Shards par Nœud (Approx.) : En utilisant la règle des
10-20 shards par Go de tas, un nœud avec un tas de 30 Go pourrait héberger30 * 10 = 300à30 * 20 = 600shards. - Total des Répliques : Si vous utilisez 1 réplique (fortement recommandé), vous aurez
60 shards primaires + 60 shards de réplique = 120 shards au total. - Nombre de Nœuds de Données : Si vous visez 120 shards au total et que chaque nœud peut gérer, disons, 300 shards (une estimation prudente dans la plage), vous pourriez exécuter ces 120 shards sur
120 / (par exemple, 60 shards par nœud)= 2 nœuds minimum. Cependant, pour la résilience et la distribution, vous voudriez généralement au moins 3 à 5 nœuds de données pour distribuer ces shards et leurs répliques efficacement, prévenant les points chauds et permettant les pannes de nœud.
Scénario Exemple
Supposons un cluster de données à 3 nœuds, chacun avec un tas de 30 Go :
- Tas Total :
3 nœuds * 30 Go/nœud = 90 Go - Nombre Maximal Total de Shards (en utilisant 10 shards/Go) :
90 Go * 10 = 900 shards - Notre nombre total de shards actuellement calculé :
120 shards (60 primaires + 60 répliques) - Ces
120 shards au totalsont bien dans la limite de 900 shards, ce qui suggère que notre estimation initiale est raisonnable. - Moyenne de shards par nœud :
120 shards au total / 3 nœuds = 40 shards par nœud. C'est un nombre très confortable pour un nœud avec un tas de 30 Go.
Étape 5 : Tester et Surveiller
C'est l'étape la plus critique. Vos calculs théoriques ne sont qu'un point de départ.
- Tests de Charge : Simulez vos modèles d'indexation et de requêtes attendus. Observez les métriques de performance.
-
Outils de Surveillance : Utilisez la surveillance intégrée de Kibana, les API
_catd'Elasticsearch, ou des outils de surveillance externes (par exemple, Prometheus, Grafana) pour garder un œil sur :_cat/shards: Vérifiez la taille et la distribution des shards._cluster/stats: Statistiques au niveau du cluster, en particulier pour l'utilisation du tas JVM.- CPU, Mémoire et E/S Disque sur les nœuds individuels.
- Latences d'indexation et de recherche.
- Activité de fusion des segments.
```bash
Obtenir l'allocation de shard et les informations de taille
GET _cat/shards?v=true&h=index,shard,prirep,state,docs,store,node
Obtenir les statistiques du cluster pour l'utilisation du tas et le nombre de shards
GET _cluster/stats
```
Étape 6 : Ajustement Itératif
Sur la base de votre surveillance, soyez prêt à ajuster votre nombre de shards. Cela pourrait impliquer :
- API Shrink : Si vous avez trop de shards primaires pour un index qui n'est plus écrit, vous pouvez utiliser l'API
_shrinkpour réduire le nombre de shards primaires. Cela nécessite un index fermé et suffisamment d'espace. - API Split : Si les shards d'un index deviennent trop grands et que les performances en souffrent, l'API
_splitpeut augmenter le nombre de shards primaires. Cela nécessite un index ouvert. - API Reindex : Pour des changements plus complexes, tels que la modification du mapping ou le changement du nombre de shards pour un index actif et en cours d'écriture, vous pourriez avoir besoin de réindexer vos données dans un nouvel index avec une configuration de shard différente.
Pièges Courants et Comment les Éviter
- Sur-fragmentation (Over-sharding) Aveugle : Créer 1 shard par Go de données sur de petits clusters, entraînant une surcharge excessive. Évitez : Commencez avec des objectifs raisonnables et augmentez le nombre de shards à mesure que les données augmentent.
- Sous-fragmentation (Under-sharding) d'un Index : Avoir seulement 1 à 3 shards pour un très grand index, limitant la parallélisation et l'évolutivité. Évitez : Calculez en fonction du volume de données et de la capacité des nœuds.
- Ignorer les Projections de Croissance : Dimensionner pour les données actuelles sans considérer l'ingestion future. Évitez : Tenez toujours compte de la croissance des données attendue pour le cycle de vie de vos données.
- Ne Pas Surveiller : Configurer et oublier. La taille des shards, les ressources des nœuds et les performances des requêtes changent avec le temps. Évitez : Implémentez une surveillance robuste et des alertes pour les métriques clés.
- Suivre Aveuglément les Règles Empiriques : La règle des 10 Go à 50 Go est une ligne directrice, pas une loi stricte. Votre charge de travail spécifique peut dicter des variations. Évitez : Validez toujours les recommandations générales avec vos données réelles et vos modèles d'utilisation.
Conclusion
Le dimensionnement des shards Elasticsearch est un aspect nuancé mais critique de la construction d'un cluster performant, évolutif et résilient. Il implique un équilibre délicat entre la maximisation du traitement parallèle et la minimisation de la surcharge de gestion. En comprenant les facteurs qui influencent le dimensionnement des shards, les compromis des différentes configurations, et en mettant en œuvre une stratégie itérative de calcul, de test et de surveillance, vous pouvez atteindre un équilibre optimal adapté à vos besoins spécifiques.
N'oubliez pas que les exigences de votre cluster évolueront. Une surveillance régulière et une volonté d'adapter votre stratégie de dimensionnement des shards sont essentielles pour maintenir un environnement Elasticsearch sain et performant à mesure que vos données et votre charge de travail augmentent.