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.
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ère | Elasticsearch 9.5 | OpenSearch 3.8 |
|---|---|---|
| Licence | SSPL, ELv2 ou AGPLv3 (option) | Apache 2.0 |
| Gouvernance | Elastic N.V. | OpenSearch Software Foundation (Linux Foundation) |
| Sécurité (auth, RBAC, TLS) | Incluse dans la basic gratuite | Plugin security inclus, gratuit |
| Console web | Kibana | OpenSearch Dashboards |
| SQL / PPL | SQL basic ; ES|QL depuis 8.11 | Plugin sql : SQL et PPL, gratuits |
| Recherche vectorielle | dense_vector, kNN natif, ELSER, semantic_text | Plugin k-NN, Neural Search |
| Alerting | Basic + niveaux payants | Plugin Alerting inclus, gratuit |
| Cycle de vie des index | ILM | ISM (Index State Management), plugin |
| Clients officiels | elasticsearch v8 / v9 | opensearch-py, forks pour JS, Java, Go |
| Compatibilité inter-clients | Client v8+ non compatible OpenSearch | Client OpenSearch non recommandé pour Elastic |
| Hébergeurs managés | Elastic Cloud, Bonsai, Aiven | AWS 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é.
_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, auditsql: SQL et PPL sur les indicesk-NN: recherche vectorielle exacte et approchéeneural-search: intégration d'embeddingsalerting: moniteurs et destinations (Slack, mail, webhook)anomaly-detection: détection non superviséeindex-management(ISM) : politiques de cycle de vienotifications,ml-commons,observability,flow-framework
Critères de décision pour Veille
Cinq questions concrètes à trancher en équipe.
- 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.
- 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.
- Quel hébergeur ? Elastic Cloud d'un côté, AWS OpenSearch Service de l'autre ; les deux existent aussi chez Aiven et Bonsai.
- Quel écosystème d'IA de recherche ? ELSER et
semantic_textsont un avantage Elastic net en 2026 ; k-NN natif et Neural Search côté OpenSearch restent solides mais demandent plus de plomberie. - Quels clients ? Si Karim écrit son API Python contre
elasticsearchv9, migrer signifie passer àopensearch-py(import, quelques options renommées, quelques réponses différentes dans les métadonnées).
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.
_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:veillecôté Elastic,veille-oscôté OpenSearch.- Les champs
active_shards_percent_as_numberetunassigned_primary_shardssont formatés différemment selon la version. - OpenSearch expose
discovered_master(compatibilité), Elasticsearch exposediscovered_cluster_manageretdiscovered_masteren 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._xpackdevient_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 ;
_reindexremote 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 :
elasticsearchv9 n'est pas fait pour parler à OpenSearch, et réciproquement pouropensearch-py.
Si ça ne marche pas
opensearch-upéchoue avecmax_map_countou OOM → contrainte kernel identique à Elasticsearch, mémoire à augmenter →./lab.sh doctordonne 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-downpuis relance. - Dashboards affiche « OpenSearch cluster is not ready » → laisser 1 à 2 min au premier démarrage, ou
./lab.sh logs opensearchpour lire le message d'erreur réel. _reindexremote refusé (400reindex.remote.whitelist) → l'hôte source n'est pas listé dansopensearch.yml→ ajouterreindex.remote.whitelist: "elasticsearch:9200"et redémarrer OpenSearch.
Pour aller plus loin
- Documentation OpenSearch : https://docs.opensearch.org/
- Query DSL et PPL : https://docs.opensearch.org/latest/query-dsl/
- Fondation et gouvernance : https://opensearch.org/foundation/
- Migration depuis Elasticsearch : https://docs.opensearch.org/latest/migration-assistant/
- Blog d'annonce du fork (référence historique) : https://opensearch.org/blog/introducing-opensearch/
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.