Elasticsearch - Comment copier un index sur une autre instance ?
Contexte
Nous avons deux instances Elasticsearch distinctes (qui ne sont pas dans le même cluster). Le but est de regarder ensemble les solutions qui existent pour copier un index d’une instance à l’autre.
Nous allons utiliser l’outil curl
pour interagir avec elasticsearch. Comme cela est fortement conseillé depuis longtemps et par défaut maintenant, les accès sont sécurisés et protégés par un certificat SSL. Je suis resté avec le certificat auto-généré par défaut. C’est pourquoi j’ajoute l’option --insecure
au niveau de la commande curl
curl --request GET \
--insecure \
--url https://ADR_IP_INSTANCE_A:9200/ \
--header 'Authorization: Basic ZWxhc3RpYzo0ZFpQUFlTRExaSWpOQmFQUGZVUw=='
Voici le résultat :
{
"name": "localhost",
"cluster_name": "elasticsearch",
"cluster_uuid": "xJqE_y6GS2OuWNaNpSrn3A",
"version": {
"number": "8.9.0",
"build_flavor": "default",
"build_type": "tar",
"build_hash": "8aa461beb06aa0417a231c345a1b8c38fb498a0d",
"build_date": "2023-07-19T14:43:58.555259655Z",
"build_snapshot": false,
"lucene_version": "9.7.0",
"minimum_wire_compatibility_version": "7.17.0",
"minimum_index_compatibility_version": "7.0.0"
},
"tagline": "You Know, for Search"
}
Utilisation de la réindexation
La première possibilité est de passer par une demande de réindexation de l’instance B depuis un index hébergé sur l’instance A.
Pré-requis : l’instance A doit être accessible via le réseau pour l’instance B.
Il est nécessaire d’ajouter l’instance A dans la liste blanche comme source pour la réindexation au niveau de l’instance B.
Pour cela, il faut modifier le fichier elasticsearch.yml
de l’instance B pour rajouter la ligne suivante :
....
reindex.remote.whitelist: [ADR_IP_INSTANCE_A:9200]
Il sera nécessaire de redémarrer l’instance afin que la configuration soit prise en compte.
Maintenant, il reste plus qu’à lancer la commande pour démarrer la réindexation sur l’instance B.
Cela se fait avec une simple commande curl
(ou équivalent permettant d’utiliser la méthode POST)
curl --request POST --insecure \
--url httsp://ADR_IP_INSTANCE_B:9200/_reindex \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic CHAINE_ENCODE_A_RENSEIGNER_ICI' \
--data '{
"source": {
"remote": {
"host": "https://ADR_IP_INSTANCE_A:9200",
"username": "elastic",
"password": "MOT_A_PASSE_A_RENSEIGNER_ICI"
},
"index": "mon-index",
"query": {
"match_all": {}
}
},
"dest": {
"index": "mon-index"
}
}'
Si tout se passe bien, vous obtenez le résultat suivant :
{
"took": 294,
"timed_out": false,
"total": 1,
"updated": 0,
"created": 1,
"deleted": 0,
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1.0,
"throttled_until_millis": 0,
"failures": []
}
Vous pouvez utiliser la commande _stats pour surveiller la réindexation
Exemple avec curl
:
curl --insecure --header 'Authorization: Basic CHAINE_ENCODE_A_RENSEIGNER_ICI' \
--url https://ADR_IP:9200/mon-index/_stats
Consulter la documentation de l’Api REINDEX d’elasticsearch. Cette dernière est très riche.
Utilisation de la sauvegarde et restauration
La sauvegarde
La première étape est de définir un dépôt de sauvegarde (backup) au niveau de l’instance A. Pour cela, nous modifions le fichier elasticsearch.yml
et rajouter la ligne suivante
path.repo: /datas/es-a/repo
Pré-requis : le répertoire /datas/es-a/repo devra exister avant le redémarrage.
Un redémarrage de l’instance A est nécessaire afin que la nouvelle configuration soit prise en compte.
A partir de ce moment, nous allons pouvoir passer à la seconde étape en définissant le répertoire pour la sauvegarde grâce à la commande curl
suivante :
curl --request POST \
--insecure --header 'Authorization: Basic CHAINE_ENCODE_A_RENSEIGNER_ICI==' \
--url https://ADR_IP_INSTANCE_A:9200/_snapshot/backups \
--header 'Content-Type: application/json' \
--data '{
"type": "fs",
"settings": {
"location": "/datas/es-a/repo/backups"
}
}'
Nous obtenons la réponse suivante :
{
"acknowledged": true
}
Maintenant, nous allons pouvoir lancer la sauvegarde.
curl --request POST \
--insecure --header 'Authorization: Basic CHAINE_ENCODE_A_RENSEIGNER_ICI' \
--url https://localhost:9200/_snapshot/backups/backup_20230730?wait_for_completion=true
L’ajout du paramètre wait_for_completion
permet d’attendre que l’opération soit terminée. Ainsi quand la commande nous rend la main, la sauvegarde est faite.
Inversement, il est préférable d’utiliser cette option si la sauvegarde s’exécute dans un temps raisonnable.
Voici le résultat (mon index mon-index
est très petit)
{
"snapshot": {
"snapshot": "backup_20230730",
"uuid": "xXYjHpcDRHmRXlN9ey3XXA",
"repository": "backups",
"version_id": 8090099,
"version": "8.9.0",
"indices": [
"mon-index",
".security-7"
],
"data_streams": [],
"include_global_state": true,
"state": "SUCCESS",
"start_time": "2023-07-30T11:56:49.099Z",
"start_time_in_millis": 1691150209099,
"end_time": "2023-07-30T11:56:49.299Z",
"end_time_in_millis": 1691150209299,
"duration_in_millis": 200,
"failures": [],
"shards": {
"total": 2,
"failed": 0,
"successful": 2
},
"feature_states": [
{
"feature_name": "security",
"indices": [
".security-7"
]
}
]
}
}
Nous allons pouvoir créer l’archive. Pour cela, nous allons nous déplacer dans le répertoire où se trouve la sauvegarde. Dans notre cas, c’est le répertoire /datas/es-a/repo/backups/backup_20230730, puis de créer l’archive avec la commande tar
en incluant toue le contenu du répertoire
cd /datas/es-a/repo/backups/backup_20230730
tar czvf ../backups-20230730.tar.gz *
La sauvegarde est terminée.
La restauration
Nous allons pouvoir continuer avec la restauration.
Comme tout à l’heure, il est nécessaire de définir un dépôt repo pour la restauration (restore) au niveau de l’instance B. Pour cela, nous modifions sur le fichier elasticsearch.yml
et rajouter la ligne suivante
path.repo: /datas/es-b/repo
Pré-requis : le répertoire /datas/es-b/repo devra exister avant le redémarrage.
Un redémarrage de l’instance B est nécessaire afin que la nouvelle configuration soit prise en compte.
Nous allons créer physiquement le répertoire restore
cd /datas/es-b/repo
mkdir restore
Dans le répertoire, il faut décompresser l’archive précédente.
cd /datas/es-b/repo/restore
tar xzvf backups-20230717.tar.gz
rm backups-20230717.tar.gz
Vérifier que les droits des fichiers soient corrects. C’est à dire que l’utilisateur utilisé pour exécuter elasticsearch doit avoir les droits sur ces fichiers.
Dans un premier temps, nous allons déclarer le répertoire au niveau d’Elasticsearch, avec la commande suivante:
curl --request POST \
--insecure --header 'Authorization: Basic CHAINE_ENCODE_A_RENSEIGNER_ICI' \
--url https://ADR_IP_INSTANCE_B:9200/_snapshot/restore \
--header 'Content-Type: application/json' \
--data '{
"type": "url",
"settings": {
"url": "file:/datas/socle/repo/restore"
}
}'
Nous obtenons la réponse suivante :
{
"acknowledged": true
}
Nous allons pouvoir lister les sauvegardes possibles :
curl --request GET \
--insecure --header 'Authorization: Basic CHAINE_ENCODE_A_RENSEIGNER_ICI' \
--url 'https://ADR_INSTANCE_B:9200/_snapshot/restore/*?verbose=false'
Nous obtenons le résultat suivant :
{
"snapshots": [
{
"snapshot": "backup_20230730",
"uuid": "xXYjHpcDRHmRXlN9ey3XXA",
"repository": "restore",
"indices": [
".security-7",
"mon-index"
],
"data_streams": [],
"state": "SUCCESS"
}
],
"total": 1,
"remaining": 0
}
Nous avons bien notre sauvegarde backup_20230730 contenant deux index dont mon-index
Maintenant, nous allons pouvoir lancer la restauration avec la commande suivante :
curl --request POST \
--insecure --header 'Authorization: Basic CHAINE_ENCODE_A_RENSEIGNER_ICI' \
--url https://ADR_INSTANCE_B:9200/_snapshot/restore/backup_20230730/_restore \
--header 'Content-Type: application/json' \
--data '{
"indices": "mon-index"
}'
Dans le cas ci-dessus, j’ai filtré pour restaurer uniquement l’index qui m’intéresse.
En retour, vous obtenez le message suivant :
{
"accepted": true
}
Il faudra attendre en fonction du volume des données mais sinon voila le tour est joué.
Moteur de recherche
"Eduquer, ce n'est pas remplir des vases mais c'est d'allumer des feux." - Michel Montaigne
Billets récents
- Eclipse plante systématiquement sous Debian (et autres distribution Linux)
- JEP 463, Implicitly Declared Classes and Instance Main Methods (Second Preview)
- Debian - Montée de version de Debian 11 (Bullseye) à Debian 12 (Bookworm)
- JEP 451, Prepare to Disallow the Dynamic Loading of Agents
- JEP 444, Virtual Threads