RousselTMLEARNING

Observabilité

Bonnes pratiques Elasticsearch : mappings, shards, cycle de vie et exploitation

Bonnes pratiques Elasticsearch : dimensionnement des shards, mappings explicites, templates, ILM, mémoire JVM, sécurité, snapshots, requêtes performantes et commandes de diagnostic.

1. Dimensionner les index et les shards #

Le réglage le plus impactant.

Règles de dimensionnement #

Taille recommandée des shards
Trop de petits shards consomment de la mémoire ; trop gros, ils ralentissent la récupération.
  • Visez 10 à 50 Go par shard. L'ancienne règle « moins de 20 shards par Go de heap » a été retirée par Elastic depuis la 8.3 : surveillez plutôt la limite cluster.max_shards_per_node et la mémoire réellement utilisée par les mappings et les champs.
  • Un seul shard primaire suffit pour les petits index ; évitez le sur-sharding.
  • Utilisez des data streams avec rollover plutôt qu'un index unique géant.
# Toutes les commandes utilisent HTTPS et l'authentification (ca.crt : certificat de l'autorité du cluster)
export ES_PASSWORD='...'
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s https://localhost:9200/_cluster/health?pretty
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s 'https://localhost:9200/_cat/indices?v&s=store.size:desc&h=index,pri,rep,docs.count,store.size' | head
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s 'https://localhost:9200/_cat/shards?v&s=store:desc' | head
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s 'https://localhost:9200/_cat/allocation?v'
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s 'https://localhost:9200/_cluster/allocation/explain?pretty'      # pourquoi un shard n'est pas alloué

2. Mappings, templates et ILM #

Maîtriser le schéma et le cycle de vie.

Template et mapping explicite #

curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -X PUT https://localhost:9200/_index_template/logs-app -H 'Content-Type: application/json' -d '{
  "index_patterns": ["logs-app-*"],
  "data_stream": {},
  "priority": 200,
  "template": {
    "settings": { "number_of_shards": 1, "number_of_replicas": 1, "index.lifecycle.name": "logs-30j", "index.codec": "best_compression" },
    "mappings": {
      "dynamic": "strict",
      "properties": {
        "@timestamp": { "type": "date" }, "level": { "type": "keyword" }, "message": { "type": "text" },
        "user_id": { "type": "keyword" }, "duration_ms": { "type": "long" }
      }
    }
  }
}'
Erreur Courante : Un mapping dynamique laissé libre crée des milliers de champs (explosion de mapping). Utilisez dynamic: strict et des types adaptés (keyword pour les filtres, text pour le plein texte).
À savoir : Le template porte une priorité de 200 : sans elle, il chevauche le template intégré logs-*-* (priorité 100) et le data stream peut recevoir le mapping intégré au lieu du vôtre. Vérifiez le template appliqué avec POST _index_template/_simulate_index/logs-app-default.

Cycle de vie (ILM) #

curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -X PUT https://localhost:9200/_ilm/policy/logs-30j -H 'Content-Type: application/json' -d '{
  "policy": { "phases": {
    "hot":    { "actions": { "rollover": { "max_primary_shard_size": "50gb", "max_age": "1d" } } },
    "warm":   { "min_age": "7d",  "actions": { "forcemerge": { "max_num_segments": 1 } } },
    "delete": { "min_age": "30d", "actions": { "delete": {} } }
  } }
}'
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s https://localhost:9200/_ilm/status
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s 'https://localhost:9200/logs-app-*/_ilm/explain?pretty' | head -30

3. Mémoire, sécurité et sauvegardes #

Stabilité de production.

JVM et système #

# jvm.options.d/heap.options : 50 % de la RAM maximum, jamais plus de ~30 Go
-Xms16g
-Xmx16g

sudo sysctl -w vm.max_map_count=262144
sudo swapoff -a                       # ou bootstrap.memory_lock: true
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s 'https://localhost:9200/_nodes/stats/jvm?filter_path=**.heap_used_percent&pretty'

Sécurité #

  • Activez TLS (transport et HTTP) et l'authentification ; utilisez des clés d'API à portée limitée.
  • N'exposez jamais le port 9200 sur Internet ; passez par un reverse proxy.
  • Un rôle d'écriture par pipeline d'ingestion, un rôle de lecture par équipe.
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -X POST https://localhost:9200/_security/api_key -H 'Content-Type: application/json' -d '{
  "name": "ingestion-app",
  "role_descriptors": { "writer": { "indices": [{ "names": ["logs-app-*"], "privileges": ["create_doc", "auto_configure"] }] } },
  "expiration": "90d"
}'

Sauvegardes (snapshots) #

curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -X PUT https://localhost:9200/_snapshot/depot -H 'Content-Type: application/json' -d '{ "type": "s3", "settings": { "bucket": "es-snapshots" } }'
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -X PUT https://localhost:9200/_slm/policy/quotidien -H 'Content-Type: application/json' -d '{
  "schedule": "0 30 1 * * ?", "name": "<snap-{now/d}>", "repository": "depot",
  "config": { "indices": ["logs-*"] }, "retention": { "expire_after": "30d", "min_count": 5 } }'
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s https://localhost:9200/_snapshot/depot/_all?pretty | head -20
Bonne Pratique : Testez régulièrement la restauration : une sauvegarde jamais restaurée n'est pas une sauvegarde.

4. Requêtes et ingestion performantes #

Bulk, filtres et pagination.

Bonnes habitudes #

# Ingestion : _bulk par lots de 5 à 15 Mo
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s -H 'Content-Type: application/x-ndjson' -XPOST https://localhost:9200/_bulk --data-binary @lot.ndjson | jq '.errors'

# Filtres (cachés, sans score) plutôt que must pour les conditions exactes
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s https://localhost:9200/logs-app-*/_search -H 'Content-Type: application/json' -d '{
  "size": 20, "_source": ["@timestamp","level","message"],
  "query": { "bool": { "filter": [ { "term": { "level": "error" } }, { "range": { "@timestamp": { "gte": "now-15m" } } } ] } },
  "sort": [{ "@timestamp": "desc" }]
}'
# Pagination profonde : search_after + PIT
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s -XPOST 'https://localhost:9200/logs-app-*/_pit?keep_alive=1m'
À éviterPréférer
from: 100000search_after avec PIT
wildcard en préfixe *texteAnalyseur adapté (n-gram) ou champ dédié
Mettre à jour un document en boucleRéindexer en bulk, modèle append-only
Un index par jour sans rolloverData streams et ILM

Schéma de référence et vérification rapide #

Visualiser le principe et le contrôler en ligne de commande.

Schéma de référence #

Phases ILM d'Elasticsearch
Adaptez les durées à votre besoin métier.
curl --cacert ca.crt -u "elastic:$ES_PASSWORD" -s 'https://localhost:9200/_cat/indices/logs-*?v&h=index,health,pri,store.size&s=index'

Articles liés

Architecture distribuée Elasticsearch : rôles des nœuds, shards, répliques et allocation

Comprendre le fonctionnement distribué d'Elasticsearch : rôles des nœuds, nœuds master et quorum, cluster sta…

Mappings et analyse de texte Elasticsearch : types de champs, analyseurs et mapping dynamique

Maîtriser les mappings Elasticsearch : types de champs (text, keyword, numériques, date, ip, nested), multi-f…

Ingestion Elasticsearch : Bulk API, ingest pipelines, enrich et reindex

Ingérer et transformer des données dans Elasticsearch : Bulk API, ingest pipelines et processeurs (grok, diss…

Pour aller plus loin

Soutenir

♥ SOUTENIR

Soutenez RousselTM Learning

Les formations, articles, TP et attestations restent gratuits et sans publicité intrusive. Une contribution libre, du montant de votre choix, finance l’hébergement, les environnements de TP et l’écriture de nouveaux contenus.

Contribuer avec PayPal Montant libre · carte bancaire ou compte PayPalEn savoir plus
QR code PayPal
Ou scannez ce QR code avec votre téléphone

Merci, chaque contribution compte !