Stratégie de Dimensionnement des Shards Elasticsearch : Trouver l'Équilibre Optimal

Planifiez le dimensionnement des shards Elasticsearch en équilibrant la taille des shards, la capacité des nœuds, les modèles de requêtes, le temps de récupération et la croissance.

Stratégie de Dimensionnement des Shards Elasticsearch : Trouver l'Équilibre Optimal

Elasticsearch, un moteur de recherche et d'analyse distribué puissant, doit une grande partie de son évolutivité et de ses performances à son architecture sous-jacente, en particulier au concept de shards. Les shards sont essentiellement des indices 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 impacte directement les performances, la stabilité et la rentabilité de votre cluster.

La stratégie de dimensionnement des shards Elasticsearch est un problème de planification de capacité, et non une formule unique. Vous voulez des shards suffisamment grands pour éviter les frais généraux de métadonnées, suffisamment petits pour récupérer rapidement, et en nombre suffisant pour répartir le travail d'indexation et de recherche sur vos nœuds de données.

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 un 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é de la lecture, Elasticsearch vous permet également de spécifier des shards réplicas. Un shard replica est une copie exacte d'un shard primaire. Si le nœud d'un shard primaire tombe en panne, un replica peut être promu pour prendre sa place, assurant la disponibilité des données et évitant leur perte. Les replicas servent également les requêtes de recherche, répartissant 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 réplicas correspondants. Lorsque vous recherchez, la requête est envoyée à tous les shards concernés, qui traitent leur portion de 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 donne à Elasticsearch son immense vitesse et son évolutivité.

Pourquoi le Dimensionnement des Shards est Important

Un 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êtes lentes à un gaspillage coûteux de ressources et des scénarios de récupération instables.

Performance

  • Vitesse de Requête : Un shard bien dimensionné peut traiter les requêtes efficacement. Des shards trop petits signifient plus de frais généraux de coordination ; des shards trop grands signifient des temps de recherche individuels plus longs.
  • Débit d'Indexation : De même, les performances d'indexation peuvent être impactées. Si les shards sont trop petits, les frais généraux de gestion de nombreux shards peuvent ralentir les écritures. Si les shards sont trop grands, les performances individuelles des shards peuvent 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é

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é tôt, car vous ne pouvez pas répartir la charge de travail au-delà du nombre de shards primaires.

Récupération et Stabilité

  • Pannes de Nœuds : Lorsqu'un nœud tombe en panne, Elasticsearch doit réallouer ses shards primaires (en promouvant des réplicas) et recréer les réplicas perdus. Le temps nécessaire est directement proportionnel à la taille et au nombre de shards impliqués.
  • Récupération du Cluster : Les grands shards mettent plus de temps à récupérer et à se répliquer, augmentant la fenêtre de vulnérabilité lors des pannes de nœuds ou des redémarrages de cluster.

Facteurs Influençant le Dimensionnement des Shards

Déterminer la bonne taille de shard n'est pas une solution universelle. Cela dépend de plusieurs facteurs interdépendants spécifiques à votre cas d'utilisation et à votre infrastructure.

  • Volume de Données et Croissance : La taille actuelle de vos données et le taux de croissance projeté sont fondamentaux. Un index statique de 100 Go aura des exigences différentes d'un index roulant croissant de 1 To par jour.
  • Taille des Documents et Complexité du Schéma : Les indices 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 : Si votre cluster est principalement utilisé pour la recherche, vous pourriez privilégier un nombre plus élevé de shards plus petits pour maximiser la parallélisation et minimiser les temps de recherche individuels.
    • Axé sur l'Analytique (agrégations) : Les grandes agrégations pourraient mieux fonctionner avec des shards plus grands, car les frais généraux de combinaison des résultats de nombreux petits shards peuvent devenir significatifs.
  • Taux d'Indexation : Des taux d'indexation élevés pourraient bénéficier de plus de shards pour répartir la charge d'écriture, mais un trop grand nombre peut introduire des frais généraux.
  • 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. Des 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 répartir les shards impacte directement le nombre réalisable de shards.

Les Compromis : Trop de Shards vs. Trop Peu de Shards

Trouver l'équilibre optimal signifie comprendre les conséquences des deux extrêmes.

Conséquences d'un Trop Grand Nombre de Shards

Bien que plus de shards semblent offrir plus de parallélisme, il y a un point de rendements décroissants :

  • Frais Généraux Plus Élevés : Chaque shard consomme du CPU et de la mémoire (tas JVM) pour ses métadonnées, fichiers ouverts, fusions de segments, etc. Trop de shards sur un nœud entraînent une consommation globale de ressources plus élevée pour la gestion des shards eux-mêmes, laissant moins pour le traitement réel des données.
    • Astuce : Les anciennes règles de shards par tas étaient utiles comme avertissements approximatifs, mais les versions modernes d'Elasticsearch ont réduit les frais généraux de tas par shard. Néanmoins, un cluster avec des milliers de petits shards gaspille de la mémoire et rend le travail de l'état du cluster plus difficile.
  • Récupération Plus Lente : Lors des pannes de nœuds 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 restreint de shards plus grands.
  • Contention de Ressources Accrue : Lorsque de nombreux shards effectuent activement des opérations (par exemple, fusion de segments, réponse à des requêtes) sur le même nœud, ils entrent en contention pour le CPU, la mémoire et les E/S disque, entraînant des performances globalement plus lentes.
  • "Gonflement des Shards" : Un cluster avec de nombreux petits shards, pour la plupart vides, est inefficace. Il consomme des ressources pour la gestion sans bénéfices proportionnels en termes de données.

Conséquences d'un Trop Petit Nombre de Shards

Inversement, avoir trop peu de shards présente également des défis significatifs :

  • 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 répartie sur de nombreux nœuds/cœurs.
  • Points Chauds : 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, entraînant une saturation des ressources sur ce nœud spécifique.
  • Difficulté à Monter en Échelle : Si votre index a, par exemple, seulement 5 shards primaires, vous ne pouvez distribuer efficacement cet index que sur un maximum de 5 nœuds de données. Ajouter plus de nœuds 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 : Déplacer un seul très grand shard sur le réseau pendant le rééquilibrage est une opération longue et intensive en E/S, pouvant 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 convienne à tous, quelques directives largement acceptées fournissent un bon point de départ.

Taille Cible des Shards

La recommandation la plus couramment citée pour une taille de shard individuelle (après indexation et fusions potentielles) se situe entre 10 Go et 50 Go. Certaines sources l'étendent jusqu'à 100 Go pour des scénarios spécifiques (par exemple, données de séries temporelles avec des écritures principalement en ajout 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 suffisamment grands pour minimiser les frais généraux mais suffisamment 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. Elasticsearch applique des limites de shards de cluster dans les versions modernes, et votre limite pratique dépend du tas, des mappings, du volume de requêtes et de la vitesse du disque. Utilisez le nombre de shards comme métrique d'avertissement, puis confirmez avec la pression JVM, la latence de mise à jour de l'état du cluster et la latence de recherche/indexation.

Architecture Hot-Warm-Cold et Dimensionnement des Shards

Dans une architecture Hot-Warm-Cold (HWC), le dimensionnement des shards peut varier :

  • Niveau Hot : 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 pour maximiser le débit d'indexation et le parallélisme des requêtes.
  • Niveau Warm/Cold : Nœuds contenant des données plus anciennes, moins fréquemment consultées. Ces shards sont généralement plus grands, car l'indexation a cessé et les fusions sont terminées. Des shards plus grands (jusqu'à 100 Go+) peuvent être acceptables ici pour réduire le nombre total de shards et les frais généraux associés, en particulier sur un stockage optimisé en termes de coût.

Réplicas

Utilisez toujours des réplicas ! Un minimum de un replica par shard primaire (total de 2 copies de vos données) est crucial pour une haute disponibilité. Les réplicas augmentent également la capacité de lecture en distribuant les requêtes de recherche. Le nombre optimal de réplicas 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 de raffinement itératif.

Étape 1 : Estimer le Volume Total de Données et la Croissance

Projetez la quantité de données que votre index (ou vos index roulants quotidiens/mensuels) contiendra sur son cycle de vie. Considérez 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 temporelles, des indices en ajout seulement, ou des requêtes moins fréquentes et plus simples.

  • Exemple (suite de l'étape 1) : Ciblons une taille moyenne de shard primaire de 50 Go.

Étape 3 : Calculer le Nombre Initial de Shards Primaires

Divisez votre volume total estimé de données par votre taille cible de shard.

Nombre de Shards Primaires = (Volume Total de Données) / (Taille Cible du Shard)

  • Exemple : 3000 Go / 50 Go = 60 shards primaires.

Étape 4 : Considérer les Ressources du Nœud et la Taille du Tas

Déterminez combien de shards primaires et réplicas votre cluster peut héberger confortablement, en respectant la règle des shards par Go de tas.

  • Tas par Nœud : Disons que vous avez des nœuds de données avec 30 Go de tas JVM chacun.
  • Nombre Maximum de Shards par Nœud (Approx.) : En utilisant la règle des 10-20 shards par Go de tas, un nœud avec 30 Go de tas pourrait héberger 30 * 10 = 300 à 30 * 20 = 600 shards.
  • Total des Réplicas : Si vous utilisez 1 replica (fortement recommandé), vous aurez 60 shards primaires + 60 shards réplicas = 120 shards au total.
  • Nombre de Nœuds de Données : Assurez-vous que ces shards peuvent être distribués sans placer un replica sur le même nœud que son primaire. Pour une résilience en production, utilisez suffisamment de nœuds de données et de zones pour qu'une panne de nœud ou de zone ne vous laisse pas avec des réplicas non assignés.

Exemple de Scénario

Supposons un cluster de données à 3 nœuds, chacun avec 30 Go de tas :

  • Notre nombre total calculé de shards : 120 shards (60 primaires + 60 réplicas)
  • Nombre moyen de shards par nœud : 120 shards au total / 3 nœuds = 40 shards par nœud.
  • Le nombre est raisonnable seulement si la pression du tas, les E/S disque, la latence d'indexation et la latence de recherche restent saines sous charge.

É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 _cat d'Elasticsearch, ou des outils de surveillance externes (par exemple, Prometheus, Grafana) pour garder un œil sur :

    • _cat/shards : Vérifiez les tailles 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 de segments.
    # Obtenir des informations sur l'allocation et la taille des shards
    GET _cat/shards?v=true&h=index,shard,prirep,state,docs,store,node
    
    # Obtenir des 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 peut impliquer :

  • API Shrink : Si vous avez trop de shards primaires pour un index qui n'est plus écrit, vous pouvez utiliser l'API _shrink pour réduire le nombre de shards primaires. L'index doit être en lecture seule, et le placement des shards doit satisfaire les exigences de shrink.
  • API Split : Si les shards d'un index deviennent trop grands et que les performances en souffrent, l'API _split peut augmenter le nombre de shards primaires. L'index doit être en lecture seule et doit avoir été créé avec un nombre de shards de routage compatible.
  • API Reindex : Pour des changements plus complexes, comme la modification du mapping ou le changement du nombre de shards pour un index actif en écriture, vous pourriez avoir besoin de réindexer vos données dans un nouvel index avec une configuration de shards différente.

Pièges Courants et Comment les Éviter

  • Sur-dimensionnement Aveugle : Créer 1 shard par Go de données sur de petits clusters, entraînant des frais généraux excessifs. À éviter : Commencez avec des cibles raisonnables et augmentez les shards à mesure que les données croissent.
  • Sous-dimensionnement d'un Index : N'avoir que 1 à 3 shards pour un très grand index, limitant la parallélisation et l'évolutivité. À éviter : 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. À éviter : Tenez toujours compte de la croissance attendue des données pour la durée de vie de vos données.
  • Ne Pas Surveiller : Configurer et oublier. Les tailles de shards, les ressources des nœuds et les performances des requêtes changent avec le temps. À éviter : Mettez en place 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 directive, pas une loi stricte. Votre charge de travail spécifique peut dicter des variations. À éviter : Validez toujours les recommandations générales avec vos données et modèles d'utilisation réels.

En Pratique

Choisissez un nombre initial de shards à partir du volume de données attendu et d'une taille cible de shard, puis prouvez-le avec des tests de charge. Surveillez le temps de récupération, la pression du tas, les E/S disque et la latence après le rollover ou la croissance. Si les chiffres dérivent, utilisez le rollover, shrink, split ou la réindexation avant que la disposition des shards ne devienne un incident.