Dimensionnement Optimal des Shards : Équilibrer Performance et Gestion du Cluster

Maîtrisez le dimensionnement des shards Elasticsearch pour optimiser les performances du cluster. Ce guide explore les compromis entre le nombre et la taille des shards, couvrant des considérations clés comme le volume de données, la charge d'indexation et les modèles de requêtes. Apprenez les meilleures pratiques pour calculer l'allocation optimale des shards, exploiter les index basés sur le temps et mettre en œuvre la gestion du cycle de vie des index (ILM) afin de construire un cluster Elasticsearch évolutif et efficace.

Dimensionnement Optimal des Shards : Équilibrer Performance et Gestion du Cluster

Le dimensionnement des shards est l'une de ces décisions Elasticsearch qui semble simple jusqu'à ce que le cluster ait vécu quelques mois. Un shard n'est qu'un index Lucene sous le capot, mais chaque shard a des frais généraux. Trop de petits shards rendent le cluster occupé à gérer les métadonnées et de minuscules cibles de recherche. Trop peu de gros shards rendent la relocalisation, la récupération et certaines recherches douloureusement lentes.

Il n'existe pas de taille de shard universelle qui fonctionne pour tous les clusters. Un cluster de journalisation avec roulement quotidien, un index de recherche de produits et un cluster d'analyse de sécurité se comportent tous différemment. L'approche utile consiste à choisir une taille de shard cible, à concevoir le roulement ou la création d'index autour de celle-ci, puis à ajuster en fonction du comportement réel d'indexation et de requête.

Les Fondamentaux des Shards Elasticsearch

Avant de plonger dans les stratégies de dimensionnement, il est essentiel de comprendre les concepts de base :

  • Index : Une collection de documents. Dans Elasticsearch, un index est divisé en plusieurs shards.
  • Shard : Une unité de distribution. Chaque shard est un index Lucene autonome. Un index peut contenir plusieurs shards, répartis sur différents nœuds du cluster.
  • Shard Primaire : Lors de la création d'un index, un nombre de shards primaires lui est attribué. Ces shards sont l'endroit où vos données sont indexées. Vous ne pouvez pas simplement modifier number_of_shards sur un index existant, mais Elasticsearch fournit des opérations de division et de réduction dans des conditions spécifiques. De nombreuses équipes considèrent toujours le nombre de shards primaires comme une décision de conception, car le modifier ultérieurement nécessite une planification.
  • Shard Réplica : Des copies de vos shards primaires. Ils assurent la redondance et augmentent le débit de lecture. Si un shard primaire tombe en panne, un réplica peut être promu pour devenir le primaire. Le nombre de shards réplicas peut être modifié à tout moment.

Comment les Shards Impactent les Performances

  • Performances d'Indexation : Chaque shard nécessite des ressources pour l'indexation. Plus de shards signifie plus de frais généraux pour les nœuds coordinateurs qui gèrent les requêtes. Cependant, si les shards deviennent trop volumineux, l'indexation dans un seul shard peut devenir un goulot d'étranglement.
  • Performances des Requêtes : Les demandes de recherche sont distribuées à tous les shards primaires pertinents. Un nombre plus élevé de shards peut augmenter le nombre de requêtes à traiter, ce qui peut augmenter la latence. À l'inverse, de très gros shards peuvent entraîner des temps de recherche plus longs car Lucene doit travailler sur plus de données dans ce shard.
  • Gestion du Cluster : Un grand nombre de shards augmente la charge sur le nœud maître, qui est responsable de la gestion de l'état du cluster. Cela impacte également les frais généraux des opérations comme la relocalisation des shards, la création d'instantanés et la récupération.
  • Utilisation des Ressources : Chaque shard consomme de la mémoire et des E/S disque. Trop de shards peuvent épuiser les ressources du nœud, entraînant une dégradation des performances ou une instabilité du nœud.

Considérations Clés pour le Dimensionnement des Shards

La taille "idéale" d'un shard n'est pas un nombre fixe ; elle dépend de votre charge de travail spécifique, des caractéristiques de vos données et de votre matériel. Cependant, plusieurs facteurs devraient guider vos décisions :

1. Volume de Données et Taux de Croissance

  • Taille Actuelle des Données : Quelle quantité de données avez-vous dans votre index actuellement ?
  • Taux de Croissance : À quelle vitesse vos données croissent-elles ? Cela aide à prédire les futures tailles de shards.
  • Politique de Rétention des Données : Allez-vous supprimer les anciennes données ? Cela impacte la taille effective des données actives.

2. Charge d'Indexation

  • Taux d'Indexation : Combien de documents par seconde indexez-vous ?
  • Taille des Documents : Quelle est la taille moyenne des documents individuels ?
  • Débit d'Indexation : Vos nœuds peuvent-ils gérer la charge d'indexation avec la configuration actuelle des shards ?

3. Modèles de Requêtes

  • Complexité des Requêtes : Vos requêtes sont-elles de simples recherches par mot-clé ou des agrégations complexes ?
  • Fréquence des Requêtes : À quelle fréquence les requêtes sont-elles exécutées sur vos données ?
  • Exigences de Latence des Requêtes : Quels sont vos temps de réponse acceptables ?

4. Topologie du Cluster et Ressources

  • Nombre de Nœuds : Combien de nœuds y a-t-il dans votre cluster ?
  • Matériel des Nœuds : CPU, RAM et disque (le SSD est fortement recommandé pour Elasticsearch).
  • Limites de Shards : Elasticsearch inclut des limites de sécurité qui empêchent un nœud de détenir un nombre excessif de shards ouverts. Les versions récentes utilisent couramment cluster.max_shards_per_node comme garde-fou à l'échelle du cluster pour les index ouverts normaux. cluster.routing.allocation.total_shards_per_node est différent : il limite le nombre de shards d'un seul index, ou d'une portée d'allocation correspondante, pouvant être alloués à un nœud. Vérifiez votre version d'Elasticsearch avant de modifier l'un ou l'autre de ces paramètres.

Meilleures Pratiques pour l'Allocation des Shards

1. Visez une Taille de Shard Cible

Bien qu'il n'y ait pas de nombre magique, de nombreux clusters de production visent des shards autour de 10 Go à 50 Go pour les charges de travail courantes de journalisation et de recherche. Cette fourchette est un point de départ, pas une règle. Les systèmes à très haut débit ou à longue rétention peuvent choisir des shards plus grands après des tests ; les index de recherche de petites entreprises peuvent fonctionner au mieux avec un seul petit shard.

  • Trop petit (< 10 Go) : Peut entraîner des frais généraux excessifs. Chaque shard a une empreinte mémoire et contribue à la charge du nœud maître. Gérer des milliers de minuscules shards devient un fardeau opérationnel important.
  • Trop grand (> 50 Go) : Peut causer des problèmes de performances. Les opérations de fusion de segments, de récupération et de rééquilibrage prennent plus de temps. Si un gros shard tombe en panne, sa récupération peut prendre un temps considérable.

2. Envisagez des Index Basés sur le Temps

Pour les données de séries temporelles (journaux, métriques, événements), l'utilisation d'index basés sur le temps est une pratique standard et très efficace. Cela implique la création de nouveaux index pour des périodes de temps spécifiques (par exemple, quotidien, hebdomadaire, mensuel).

  • Exemple : Au lieu d'un index massif, vous pourriez avoir logs-2023.10.26, logs-2023.10.27, etc.
  • Avantages : Gestion des données plus facile (suppression des anciens index via Index Lifecycle Management - ILM), meilleures performances car les requêtes ciblent souvent les données récentes, et tailles de shards contrôlées.

3. Mettez en Œuvre la Gestion du Cycle de Vie des Index (ILM)

Les politiques ILM vous permettent d'automatiser la gestion des index en fonction de l'âge, de la taille ou du nombre de documents. Vous pouvez définir des phases pour un index (chaud, tiède, froid, supprimer) et spécifier des actions pour chaque phase, y compris la modification du nombre de réplicas, la réduction des index ou leur suppression.

  • Phase Chaude : L'index est activement écrit et interrogé. Maximisez les performances.
  • Phase Tiède : L'index n'est plus écrit mais toujours interrogé. Peut être déplacé vers du matériel moins performant, potentiellement avec moins de réplicas ou réduit.
  • Phase Froide : Rarement interrogé. Les données peuvent être déplacées vers un stockage moins cher ou des nœuds de moindre performance, selon votre licence, version et architecture Elasticsearch.
  • Phase de Suppression : Les données ne sont plus nécessaires et sont supprimées.

4. Évitez le Sur-Sharding

Le sur-sharding se produit lorsque vous avez beaucoup trop de shards pour la taille de votre cluster et le volume de données. C'est un piège courant qui entraîne de mauvaises performances et des problèmes de gestion.

  • Symptômes : Utilisation élevée du CPU sur les nœuds maîtres, mises à jour lentes de l'état du cluster, temps de récupération longs et lenteur générale.
  • Atténuation : Planifiez votre nombre de shards primaires dès le début. Pour les index basés sur le temps, commencez avec un nombre raisonnable de shards primaires par index (par exemple, 1 ou 3). Vous pouvez toujours ajouter des réplicas plus tard.

5. Ne Surabondancez Pas d'Index

De même, évitez de créer un nombre excessif d'index lorsque ce n'est pas nécessaire. Chaque index ajoute des frais généraux. Pour les données non temporelles où vous n'avez pas de mécanisme de partitionnement naturel, demandez-vous si un seul index avec un nombre de shards approprié est suffisant.

6. Tenez Compte du Paramètre number_of_shards

Lors de la création d'un index, le paramètre number_of_shards définit le nombre de shards primaires. Ce paramètre est immuable après la création de l'index.

PUT mon-index
{
  "settings": {
    "index": {
      "number_of_shards": 3,  // Exemple : 3 shards primaires
      "number_of_replicas": 1   // Exemple : 1 shard réplica
    }
  }
}
  • Astuce : Pour les index plus petits ou ceux avec une charge d'indexation/requête très faible, un seul shard primaire peut suffire. Pour les index plus grands et plus actifs, 3 ou 5 shards primaires peuvent offrir une meilleure distribution et résilience, surtout si vous prévoyez de diviser l'index plus tard (bien que la division soit complexe).

7. Rééquilibrage et Relocalisation

Elasticsearch rééquilibre automatiquement les shards pour assurer une distribution uniforme entre les nœuds. Cependant, si les shards sont trop volumineux, ces opérations peuvent être gourmandes en ressources et lentes. Des shards plus petits et plus nombreux peuvent parfois se rééquilibrer plus rapidement, mais cela est contrecarré par les frais généraux de gestion d'un plus grand nombre de shards.

8. Réglage des Performances des Requêtes

Si les performances de vos requêtes souffrent, évaluez votre stratégie de shards. Considérez :

  • Nombre de Shards : Trop de shards peuvent augmenter les frais généraux de coordination.
  • Taille des Shards : De très gros shards peuvent ralentir la fusion de segments et la recherche au sein du shard.
  • Conception de l'Index : Utilisez-vous des mappages et des analyseurs appropriés ?

Calcul de Votre Nombre Optimal de Shards

Il n'y a pas de formule unique, mais voici une approche courante :

  1. Estimez votre volume total de données par index sur son cycle de vie.
  2. Déterminez votre taille de shard cible (par exemple, 30 Go).
  3. Calculez le nombre de shards primaires nécessaires : Volume Total de Données / Taille de Shard Cible.
  4. Arrondissez au nombre entier supérieur. Cela vous donne votre number_of_shards pour l'index.
    • Exemple : Si vous attendez 90 Go de données et visez des shards de 30 Go, vous auriez besoin de 90 Go / 30 Go = 3 shards primaires.
  5. Tenez compte de la résilience et de la distribution : Pour les index critiques, envisagez d'utiliser 3 ou 5 shards primaires pour permettre une meilleure distribution et des options de récupération, même si votre volume de données initial ne l'exige pas strictement. Le compromis est une augmentation des frais généraux.
  6. Commencez de manière conservatrice : Il est généralement plus facile d'ajouter des réplicas que de modifier le nombre de shards primaires (ce qui nécessite généralement une réindexation ou des solutions de contournement complexes). En cas de doute, commencez avec moins de shards primaires et surveillez les performances.

Exemple de Scénario : Analyse de Journaux

Disons que vous indexez des journaux d'application :

  • Volume de Données : Vous attendez 1 To de journaux par mois.

  • Rétention des Données : Vous conservez les journaux pendant 30 jours.

  • Taille de Shard Cible : Vous visez 20 Go.

  • Index Quotidiens : Vous créez des index quotidiens (logstash-AAAA.MM.JJ). Chaque index quotidien contiendra environ 1 To / 30 jours ≈ 33 Go de données.

  • Shards Primaires par Index : Compte tenu de la cible de 20 Go et du volume quotidien de 33 Go, vous pourriez choisir 2 shards primaires par index (33 Go / 20 Go ≈ 1,65, arrondi à 2). Cela garantit que les shards individuels restent dans votre taille cible.

  • Réplicas : Vous décidez d'1 réplica pour une haute disponibilité.

  • Total des Shards : Sur la période de rétention de 30 jours, vous aurez 30 index, chacun avec 2 shards primaires et 2 shards réplicas, totalisant 60 shards primaires et 60 shards réplicas actifs à tout moment.

Cette approche maintient les shards individuels gérables et permet une suppression efficace des données en supprimant simplement les anciens index.

Ce Qui Tourne Généralement Mal

Le problème le plus courant est le sur-sharding par habitude. Quelqu'un crée des index quotidiens avec cinq primaires et un réplica parce qu'un ancien tutoriel utilisait ce paramètre. Cela semble inoffensif au début. Ensuite, le cluster a des centaines de petits index, des milliers de minuscules shards, et les nœuds maîtres passent trop de temps sur les mises à jour de l'état du cluster. Les recherches se répartissent également sur de nombreux shards, ce qui ajoute des frais généraux de coordination avant même que le travail de requête réel ne commence.

Le problème inverse apparaît lors de la récupération. Quelques énormes shards peuvent interroger de manière acceptable un jour normal, mais lorsqu'un nœud tombe en panne ou qu'un redémarrage progressif commence, la relocalisation prend beaucoup de temps. Les instantanés et les restaurations peuvent également devenir plus lents car chaque shard est une grande unité de travail. Si votre objectif de récupération est serré, la taille des shards compte même lorsque la latence des requêtes semble bonne.

Les shards chauds sont un autre problème pratique. Si toutes les nouvelles écritures vont vers un seul shard primaire, l'ajout de nœuds supplémentaires ne répartira pas automatiquement cette charge d'écriture. Le roulement basé sur le temps aide car les nouveaux index peuvent être dimensionnés pour le modèle de trafic actuel. Les choix de routage comptent également. Le routage personnalisé peut être puissant, mais une mauvaise clé de routage peut envoyer trop de données vers un seul shard.

Un Meilleur Modèle de Roulement

Pour les données de séries temporelles, le roulement basé sur la taille est souvent plus facile à gérer que les index quotidiens fixes. Au lieu de créer un index par jour quoi qu'il arrive, vous créez un alias d'écriture et laissez l'ILM effectuer le roulement lorsque l'index atteint une taille, un âge ou un nombre de documents cible.

PUT _ilm/policy/logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_primary_shard_size": "30gb",
            "max_age": "1d"
          }
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

Avec ce modèle, un week-end calme pourrait produire moins d'index, tandis qu'une journée chargée d'incidents peut déclencher un roulement plus tôt. Vous devez toujours choisir le nombre initial de primaires, mais le roulement empêche la croissance des shards de s'éloigner trop de la cible.

Comment Inspecter Vos Shards Actuels

Avant de changer quoi que ce soit, examinez le cluster que vous avez :

GET _cat/shards?v&h=index,shard,prirep,state,docs,store,node&s=store:desc
GET _cat/indices?v&h=index,pri,rep,docs.count,store.size,pri.store.size&s=pri.store.size:desc
GET _cluster/health

Vous recherchez des modèles : de nombreux petits shards, quelques énormes shards, des shards non attribués, un placement inégal des nœuds, ou des index dont la taille de stockage primaire est loin de votre cible prévue. Si un index a 100 Go de données primaires et cinq shards primaires, chaque primaire fait environ 20 Go avant les réplicas. Si le même index a 100 Go et 50 primaires, vous avez probablement créé des frais généraux inutiles.

Remarques Finales

Un bon dimensionnement des shards consiste moins à rechercher un nombre parfait qu'à garder le cluster facile à exploiter. Commencez avec un objectif raisonnable, utilisez l'ILM ou le roulement là où le modèle de données s'y prête, et observez ce qui se passe réellement avec la taille des shards, l'éventail des requêtes, le temps de récupération et la pression sur les nœuds. Si votre cluster est déjà sur-shardé, corrigez-le progressivement avec de nouveaux modèles d'index, le roulement, la réduction ou la réindexation, plutôt que d'essayer de forcer chaque ancien index dans une nouvelle forme à la fois.