Aller au contenu principal

Module 9 — OpenSearch et OpenSearch Dashboards : comparer, choisir, migrer

Karim relit les conditions d'utilisation d'Elastic et interpelle Inès en réunion produit : « on peut basculer sur OpenSearch pour éviter les surprises de licence quand Veille passera en SaaS ? ». L'équipe prend une matinée pour rejouer les requêtes du cours sur le fork d'AWS, comparer honnêtement les deux moteurs et décider. Ce module trace la frontière entre ce qui est identique, ce qui diverge, ce qui compte vraiment pour un produit qui vend de la recherche.

D'où vient le fork

Le point de bascule est janvier 2021. Jusque-là, Elasticsearch et Kibana étaient publiés sous licence Apache 2.0, une licence permissive qui autorise n'importe qui, y compris un hébergeur cloud, à revendre le logiciel. Elastic annonce le passage à un double SSPL / ELv2 (Server Side Public License et Elastic License 2.0) à partir de la version 7.11. Le message est explicite : AWS ne peut plus proposer son service géré sous le nom « Elasticsearch » sans négocier un accord commercial. La SSPL, dérivée de l'AGPL, exige de partager sous la même licence l'intégralité du code utilisé pour proposer le service en tant que SaaS ; l'ELv2 interdit la fourniture managée en tant que service.

Février 2021, AWS répond par le fork. Le point de départ est la dernière version Apache 2.0 : Elasticsearch 7.10.2 et Kibana 7.10.2. Le fork est renommé OpenSearch et OpenSearch Dashboards, développé publiquement, gouverné à l'origine par AWS. La version 1.0 sort à l'été 2021.

Depuis, deux évolutions notables. En 2024, Elastic ajoute AGPLv3 comme troisième option pour Elasticsearch : les utilisateurs peuvent choisir SSPL, ELv2 ou AGPLv3. C'est un retour partiel dans l'écosystème open source classique — mais la question du SaaS reste. La même année, OpenSearch quitte le giron exclusif d'AWS et rejoint la Linux Foundation au sein d'une nouvelle fondation, l'OpenSearch Software Foundation, où siègent aussi Uber, SAP, Aiven, Bytedance et d'autres. La gouvernance devient réellement multi-acteurs.

Deux moteurs, une base commune

Tout le vocabulaire du cours (index, shard, mapping, text vs keyword, agrégations, Query DSL) reste vrai des deux côtés. Les divergences sont au-dessus : administration, sécurité, plugins commerciaux, langages de requêtage récents.

Tableau comparatif

Le tableau ci-dessous suit la version 9.5.3 d'Elasticsearch livrée dans le kit et la version 3.8.0 d'OpenSearch, au moment de la rédaction.

CritèreElasticsearch 9.5OpenSearch 3.8
LicenceSSPL, ELv2 ou AGPLv3 (option)Apache 2.0
GouvernanceElastic N.V.OpenSearch Software Foundation (Linux Foundation)
Sécurité (auth, RBAC, TLS)Incluse dans la basic gratuitePlugin security inclus, gratuit
Console webKibanaOpenSearch Dashboards
SQL / PPLSQL basic ; ES|QL depuis 8.11Plugin sql : SQL et PPL, gratuits
Recherche vectorielledense_vector, kNN natif, ELSER, semantic_textPlugin k-NN, Neural Search
AlertingBasic + niveaux payantsPlugin Alerting inclus, gratuit
Cycle de vie des indexILMISM (Index State Management), plugin
Clients officielselasticsearch v8 / v9opensearch-py, forks pour JS, Java, Go
Compatibilité inter-clientsClient v8+ non compatible OpenSearchClient OpenSearch non recommandé pour Elastic
Hébergeurs managésElastic Cloud, Bonsai, AivenAWS OpenSearch Service, Aiven, Bonsai

Deux lignes méritent d'être creusées. La sécurité incluse : dans Elasticsearch, TLS, utilisateurs et rôles sont dans la licence basic gratuite depuis 2020, ce que beaucoup ignorent encore. Le kit veille-es l'utilise. Côté OpenSearch, le plugin security est intégré nativement (mais désactivé dans le profil comparatif du kit pour simplifier la lecture des URL). Les langages tuyau : ES|QL côté Elastic, PPL côté OpenSearch sont deux réponses distinctes au même besoin — remplacer les longs pipelines JSON de la Query DSL par une syntaxe linéaire lisible.

Elasticsearch (ES|QL)
FROM news | WHERE category == "POLITICS" | STATS c = COUNT() BY category | SORT c DESC

OpenSearch (PPL)
source=news | where category="POLITICS" | stats count() by category | sort -count()

Démarrer OpenSearch dans le kit

Le kit livre un profil dédié qui cohabite avec Elasticsearch en décalant les ports (9201 et 5602). La sécurité est désactivée volontairement dans ce profil pour que le module comparatif reste lisible ; en production, on activerait le plugin security et TLS.

./lab.sh opensearch-up

Attendu à la fin :

[OK] OpenSearch prêt sur http://localhost:9201 — Dashboards sur http://localhost:5602

Vérification rapide sans authentification :

GET _cluster/health

Réponse attendue :

{
"cluster_name": "veille-os",
"status": "green",
"number_of_nodes": 1,
"active_primary_shards": "(votre chiffre peut différer)"
}

Rejouer trois requêtes du cours

Le corpus News vit dans Elasticsearch, pas dans OpenSearch — c'est justement le point. Pour comparer la Query DSL sans réimporter 200 853 documents, créez un petit index de trois articles dans OpenSearch Dashboards → Dev Tools (http://localhost:5602/app/dev_tools#/console).

PUT news
{
"settings": { "number_of_shards": 1, "number_of_replicas": 0 },
"mappings": {
"properties": {
"headline": { "type": "text" },
"category": { "type": "keyword" },
"date": { "type": "date" }
}
}
}
POST news/_bulk
{ "index": {} }
{ "headline": "Change Is Here. Climate Change.", "category": "POLITICS", "date": "2017-06-02" }
{ "index": {} }
{ "headline": "How To Cook A Perfect Steak At Home", "category": "TASTE", "date": "2015-11-14" }
{ "index": {} }
{ "headline": "Reuters: Markets Watch Fed Signals", "category": "BUSINESS", "date": "2018-01-09" }

Requête 1 — recherche plein texte :

GET news/_search
{
"query": { "match": { "headline": "climate change" } }
}

Résultat attendu : un hit avec _score non nul sur l'article POLITICS. Sur le vrai corpus Elasticsearch (module 5), la même requête renvoie 2 834 résultats.

Requête 2 — agrégation terms sur category :

GET news/_search
{
"size": 0,
"aggs": {
"par_categorie": { "terms": { "field": "category", "size": 5 } }
}
}

Attendu ici : 3 buckets d'un article chacun. Sur le vrai corpus, le même bloc renverrait POLITICS 32 739, WELLNESS 17 827, ENTERTAINMENT 16 058, TRAVEL 9 887, STYLE & BEAUTY 9 649.

Requête 3 — pertinence avec bool :

GET news/_search
{
"query": {
"bool": {
"must": [{ "match": { "headline": "steak" } }],
"filter": [{ "term": { "category": "TASTE" } }]
}
}
}

Copiez ces trois requêtes telles quelles dans Kibana Dev Tools (http://localhost:5601) sur l'index news du cours : la syntaxe est identique, seuls les chiffres diffèrent. C'est la démonstration la plus claire : la Query DSL est un standard de fait partagé.

Ce qui diffère à la lecture

_xpack disparaît côté OpenSearch, remplacé par _plugins/_security, _plugins/_sql, _plugins/_knn, _plugins/_ism. Les endpoints métriques _cat/* sont conservés à l'identique.

OpenSearch Dashboards vs Kibana

L'ergonomie est cousine mais pas identique. On y retrouve Discover, Visualize, Dashboards, Dev Tools, Stack Management. Les visualisations Lens de Kibana n'existent pas encore ; OpenSearch propose l'ancien éditeur Visualize plus VisBuilder. Les fichiers d'objets sauvegardés (ndjson) exportés depuis Kibana ne sont pas garantis compatibles OpenSearch Dashboards, et réciproquement. En pratique, on reconstruit les tableaux de bord dans l'outil cible.

Plugins de première partie OpenSearch

Ils sont tous sous Apache 2.0, tous inclus dans l'image :

  • security : utilisateurs, rôles, ABAC, TLS, audit
  • sql : SQL et PPL sur les indices
  • k-NN : recherche vectorielle exacte et approchée
  • neural-search : intégration d'embeddings
  • alerting : moniteurs et destinations (Slack, mail, webhook)
  • anomaly-detection : détection non supervisée
  • index-management (ISM) : politiques de cycle de vie
  • notifications, ml-commons, observability, flow-framework

Critères de décision pour Veille

Cinq questions concrètes à trancher en équipe.

  1. La licence bloque-t-elle un usage prévu ? Veille exploite en SaaS interne, ne redistribue pas le moteur, ne vend pas de service managé « OpenSearch as a Service ». La basic Elastic gratuite couvre le besoin : SSPL n'entrave rien.
  2. Le budget d'une licence commerciale est-il envisageable ? Si Veille veut ELSER, l'authentification OIDC pour ses clients, ou du machine learning managé, il faudra une souscription Elastic Cloud ou Platinum. OpenSearch livre l'équivalent gratuit sur plusieurs de ces axes.
  3. Quel hébergeur ? Elastic Cloud d'un côté, AWS OpenSearch Service de l'autre ; les deux existent aussi chez Aiven et Bonsai.
  4. Quel écosystème d'IA de recherche ? ELSER et semantic_text sont un avantage Elastic net en 2026 ; k-NN natif et Neural Search côté OpenSearch restent solides mais demandent plus de plomberie.
  5. Quels clients ? Si Karim écrit son API Python contre elasticsearch v9, migrer signifie passer à opensearch-py (import, quelques options renommées, quelques réponses différentes dans les métadonnées).
Verdict interne pour Veille

Rester sur Elasticsearch 9 aujourd'hui. Surveiller OpenSearch tous les six mois : si l'écart de coût cloud dépasse un seuil, ou si un client exige une licence Apache 2.0 stricte, la porte reste ouverte.

Migrer un index

Deux voies, la première est presque toujours la bonne.

Voie 1 — réimporter depuis la source

C'est la voie propre. Veille possède déjà News_Category_Dataset_v2.json dans data/ ; l'importateur du kit est un script Python de 200 lignes. Le pointer sur http://localhost:9201 au lieu de http://localhost:9200, retirer l'authentification (ou la remplacer par celle du plugin security), et relancer. Le mapping est réécrit à l'identique dans OpenSearch : rien de spécifique à Elastic dans notre schéma. Aucun risque de dérive, tests reproductibles, retour arrière trivial.

Voie 2 — _reindex avec source.remote

Utile quand la source est loin ou introuvable. Officiellement supporté entre Elasticsearch 7.10.2 et OpenSearch 1.x ; au-delà, chaque combinaison de versions doit être vérifiée. Il faut d'abord autoriser l'hôte source dans opensearch.yml :

reindex.remote.whitelist: "elasticsearch:9200"

Puis, dans OpenSearch Dev Tools :

POST _reindex
{
"source": {
"remote": {
"host": "http://elasticsearch:9200",
"username": "elastic",
"password": "veille2026"
},
"index": "news"
},
"dest": { "index": "news" }
}

Cela lance un _reindex distant qui interroge l'API Elasticsearch et pousse les documents en _bulk local. Pour un corpus de 200 853 documents, comptez plusieurs minutes.

Attention au mapping

_reindex ne migre pas les mappings automatiquement. Créez l'index cible avec le bon mappings avant l'appel, sinon OpenSearch devine un mapping dynamique qui peut différer de celui d'origine (par exemple date deviné en text si la première date lue est ambiguë).

Arrêter proprement

./lab.sh opensearch-down

Cette commande stoppe les conteneurs veille-opensearch et veille-os-dashboards sans supprimer le volume os-data. Le prochain ./lab.sh opensearch-up reprend l'état. Un ./lab.sh reset supprimerait tout, y compris les données OpenSearch.

À vous

Exercice 1 — Lancez OpenSearch, exécutez GET _cluster/health sur les deux moteurs et notez trois différences dans la réponse JSON.

Solution
  • cluster_name : veille côté Elastic, veille-os côté OpenSearch.
  • Les champs active_shards_percent_as_number et unassigned_primary_shards sont formatés différemment selon la version.
  • OpenSearch expose discovered_master (compatibilité), Elasticsearch expose discovered_cluster_manager et discovered_master en synonyme jusqu'à la 8, puis renomme complètement.

Exercice 2 — Écrivez la même requête terms sur category (top 5) qui donnerait POLITICS 32 739, WELLNESS 17 827, ENTERTAINMENT 16 058, TRAVEL 9 887, STYLE & BEAUTY 9 649 sur le corpus Elasticsearch. Rappel : size: 0 pour n'avoir que les buckets.

Solution
GET news/_search
{
"size": 0,
"aggs": {
"categories": {
"terms": { "field": "category", "size": 5 }
}
}
}

La même requête tapée dans Kibana Dev Tools renverrait exactement les cinq buckets ci-dessus ; dans OpenSearch Dashboards sur les trois documents de démo, elle renvoie trois buckets d'un article.

Exercice 3 — Rédigez pour Inès une note interne de cinq lignes : « Doit-on rester sur Elasticsearch ? ». Argumentez sur licence, sécurité, coût et écosystème.

Solution

Une note possible : « Nous restons sur Elasticsearch pour l'instant. La basic gratuite couvre notre besoin de sécurité, ELSER et semantic_text accélèrent la recherche sémantique du produit, et la migration vers OpenSearch reste réversible via un réimport depuis News_Category_Dataset_v2.json. Nous réévaluons dans six mois selon (1) le coût Elastic Cloud, (2) les exigences de licence de nos clients grands comptes, (3) l'état de PPL et des plugins ML côté OpenSearch. »

Points à retenir

  • Le fork date de janvier 2021 : Elastic change la licence à partir de la 7.11, AWS forke depuis Elasticsearch 7.10.2 sous Apache 2.0.
  • 2024 apporte AGPLv3 côté Elastic (option) et la Linux Foundation comme tutelle d'OpenSearch.
  • Query DSL, agrégations, _cat/* : quasi identiques. _xpack devient _plugins/_*.
  • PPL côté OpenSearch, ES|QL côté Elastic : deux langages tuyau alignés sur le même besoin.
  • Migrer un index se fait presque toujours par réimport depuis la source ; _reindex remote est un plan B.
  • Pour Veille en 2026, Elasticsearch reste le choix par défaut ; OpenSearch entre en jeu si la licence, le coût cloud ou une exigence contractuelle bascule.
  • Ne mélangez pas les clients : elasticsearch v9 n'est pas fait pour parler à OpenSearch, et réciproquement pour opensearch-py.

Si ça ne marche pas

  • opensearch-up échoue avec max_map_count ou OOM → contrainte kernel identique à Elasticsearch, mémoire à augmenter → ./lab.sh doctor donne la commande sysctl et la valeur cible.
  • Port 9201 déjà pris → un ancien conteneur OpenSearch traîne d'un atelier précédent → ./lab.sh opensearch-down puis relance.
  • Dashboards affiche « OpenSearch cluster is not ready » → laisser 1 à 2 min au premier démarrage, ou ./lab.sh logs opensearch pour lire le message d'erreur réel.
  • _reindex remote refusé (400 reindex.remote.whitelist) → l'hôte source n'est pas listé dans opensearch.yml → ajouter reindex.remote.whitelist: "elasticsearch:9200" et redémarrer OpenSearch.

Pour aller plus loin

Module suivant : bases de graphes, Neo4j et premiers pas en Cypher — vous poserez le mini-graphe de l'équipe Veille avant de charger le graphe News.