comment renommer un index dans un cluster?

110

J'ai besoin de renommer plusieurs index dans un cluster (leur nom doit être changé, je ne peux pas utiliser d' alias ).

J'ai vu qu'il n'y avait pas de moyens pris en charge pour le faire, le plus proche que j'ai trouvé est de renommer le répertoire de l'index , j'ai essayé cela dans un cluster.

Le groupe dispose de 3 machines A, Bet Cet les tessons sont répliquées sur chacun d'eux. J'ARRÊTER ElasticSearch sur A, renommé /var/lib/elasticsearch/security/nodes/0/indices/oldindexnamepour /var/lib/elasticsearch/security/nodes/0/indices/newindexnameet redémarré A.

L'état du cluster était jaune et elasticsearch faisait de la magie pour restaurer un état correct. Après un certain temps, je me suis retrouvé avec

  • oldindexnameêtre disponible et entièrement répliqué (récupéré de Bet Cje suppose)
  • newindexname étant disponible (je peux le rechercher) mais le plugin head montre que ses fragments sont dans un état "Non attribué" et qu'ils sont grisés (non répliqués)

Pendant la récupération, security.logle message suivant a été affiché:

[2015-02-20 11:02:33,461][INFO ][gateway.local.state.meta ] [A.example.com] dangled index directory name is [newindexname], state name is [oldindexname], renaming to directory name

Bien qu'il newindexnamesoit consultable, il n'est certainement pas dans un état normal.

Je suis revenu à l'état précédent en supprimant newindexname. Le cluster est revenu au vert sans aucune entrée «Non attribué».

Étant donné que, comment puis - je renommer oldindexnameà newindexnameun cluster?

Remarque: la solution ultime je pense est de défilement copie oldindexdans newindexet supprimer par la oldindexsuite. Cela va prendre du temps, donc s'il y a une solution plus directe, ce serait formidable.

WoJ
la source

Réponses:

19

À partir d'ElasticSearch 7.4, la meilleure méthode pour renommer un index est de copier l'index à l'aide de la nouvelle API Clone Index , puis de supprimer l'index d'origine à l'aide de l' API Delete Index .

Le principal avantage de l'API Clone Index par rapport à l'utilisation de l'API Snapshot ou de l'API Reindex dans le même but est la rapidité, car l'API Clone Index relie en dur les segments de l'index source à l'index cible, sans aucun retraitement de son contenu (sur systèmes de fichiers qui prennent en charge les liens physiques, évidemment; sinon, les fichiers sont copiés au niveau du système de fichiers, ce qui est encore beaucoup plus efficace que les alternatives). L'index de clonage garantit également que l'index cible est identique en chaque point à l'index source (c'est-à-dire qu'il n'est pas nécessaire de copier manuellement les paramètres et les mappages, contrairement à l'approche de réindexation), et ne nécessite pas la configuration d'un répertoire de snapshot local .

Remarque: même si cette procédure est beaucoup plus rapide que les solutions précédentes, elle implique toujours des temps d'arrêt. Il existe des cas d'utilisation réels qui justifient le changement de nom des index (par exemple, dans le cadre d'un workflow de fractionnement, de réduction ou de sauvegarde), mais le changement de nom des index ne doit pas faire partie des opérations quotidiennes. Si votre flux de travail nécessite un changement de nom d'index fréquent, vous devez envisager d'utiliser à la place des alias d'indices .

Voici un exemple d'une séquence complète des opérations de renommer l' index source_indexpour target_index. Il peut être exécuté à l'aide d'une console spécifique à ElasticSearch, telle que celle intégrée à Kibana . Consultez cet aperçu pour une version alternative de cet exemple, en utilisant curlau lieu d'une console Elastic Search.

# Make sure the source index is actually open
POST /source_index/_open

# Put the source index in read-only mode
PUT /source_index/_settings
{
  "settings": {
    "index.blocks.write": "true"
  }
}

# Clone the source index to the target name, and set the target to read-write mode
POST /source_index/_clone/target_index
{
  "settings": {
    "index.blocks.write": null 
  }
}

# Wait until the target index is green;
# it should usually be fast (assuming your filesystem supports hard links).
GET /_cluster/health/target_index?wait_for_status=green&timeout=30s

# If it appears to be taking too much time for the cluster to get back to green,
# the following requests might help you identify eventual outstanding issues (if any)
GET /_cat/indices/target_index
GET /_cat/recovery/target_index
GET /_cluster/allocation/explain

# Delete the source index
DELETE /source_index
Jwatkins
la source
163

Vous pouvez utiliser REINDEX pour ce faire.

La réindexation ne tente pas de configurer l'index de destination. Il ne copie pas les paramètres de l'index source. Vous devez configurer l'index de destination avant d'exécuter une action _reindex, y compris la configuration des mappages, du nombre de partitions, des réplicas, etc.

  1. Copiez d'abord l'index sous un nouveau nom
POST /_reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}
  1. Supprimez maintenant l'index
DELETE /twitter
reto
la source
Bien que cela nécessite de l'espace pour les deux index (temporairement), c'est simple et entièrement sur le serveur - cela semble donc être la meilleure solution à ce jour (même si la documentation met en garde contre un statut `` expérimental ''). Je vous remercie.
WoJ
2
Cela fonctionne-t-il si le mappage l'a fait _source: {enabled: false}?
Harald
2
@Harald Non, _reindexutilise _sourcecomme données de document d'origine.
Agop
6
Cela ne copiera pas le mappage de twitterpour new_twitterautant que je sache.
Nick
3
Je suis d'accord sur la solution de _reindex, mais la question devrait être modifiée. La réindexation n'est pas simplement un changement de nom. Cela peut même changer la façon dont les données sont indexées.
lucabelluccini
62

Pour renommer votre index, vous pouvez utiliser le module Elasticsearch Snapshot.

Vous devez d'abord prendre un instantané de votre index. En le restaurant, vous pouvez renommer votre index.

    POST /_snapshot/my_backup/snapshot_1/_restore
    {
     "indices": "jal",
     "ignore_unavailable": "true",
     "include_global_state": false,
     "rename_pattern": "jal",
     "rename_replacement": "jal1"
     }

rename_replacement: -Nouveau nom d'index dans lequel vous souhaitez sauvegarder vos données.

Krishna Kumar
la source
4
Holycrap, c'est incroyablement utile. Je vous remercie!
Chris Cogdon
1
Bien mieux que la solution acceptée! Il s'agit en fait d'une copie binaire de l'index, donc aucun risque de perdre quoi que ce soit et ne nécessite pas _sourced'être activé dans l'index. J'ai renommé certains indices multi-TB de cette façon sans aucun problème.
Veste
2
@Jacket - Je suis heureux de savoir que ma réponse vous aide vraiment.
krishna kumar
1
Je suis d'accord, bien meilleure solution, pas de problème de perte de données, beaucoup plus rapide aussi bien pour les gros indices que la réindexation
Romain Hautefeuille
1
conserve-t-il la cartographie?
Amogh Mishra
5

En tant que tel, il n'y a pas de méthode directe pour copier ou renommer l'index dans ES (j'ai fait une recherche approfondie pour mon propre projet)

Cependant, une option très simple consiste à utiliser un outil de migration populaire [Elastic-Exporter].

http://www.retailmenot.com/corp/eng/posts/2014/12/02/elasticsearch-cluster-migration/

[PS: ce n'est pas mon blog, je suis juste tombé dessus et je l'ai trouvé bon]

Vous pouvez ainsi copier l'index / le type, puis supprimer l'ancien.

paresseux
la source
Le lien ne fonctionne plus. Un autre endroit où nous pourrions le trouver ou avoir cette information?
elachell
5

Si vous ne pouvez pas REINDEX, une solution de contournement consiste à utiliser des alias . De la documentation officielle :

Les API dans elasticsearch acceptent un nom d'index lorsqu'elles travaillent sur un index spécifique, et plusieurs index le cas échéant. L'API d'alias d'index permet d'aliaser un index avec un nom, toutes les API convertissant automatiquement le nom d'alias en nom d'index réel. Un alias peut également être mappé à plusieurs index, et lors de sa spécification, l'alias se développera automatiquement vers les index d'alias. Un alias peut également être associé à un filtre qui sera automatiquement appliqué lors de la recherche et du routage des valeurs. Un alias ne peut pas avoir le même nom qu'un index.

Sachez que cette solution ne fonctionne pas si vous utilisez la fonctionnalité More Like This. https://github.com/elastic/elasticsearch/issues/16560

Leo
la source
1
I need to rename several indexes in a cluster (their name must be changed I cannot use aliases).Par @WoJ
Thales P
L'alias de raison ne fonctionnera pas : l'utilisation vous alias oblige à planifier à l'avance et à créer le nom d'index d'origine as an aliasdans un index réel. Ensuite, vous pouvez créer un nouveau nom d'alias et réutiliser l'ancien nom d'alias pour autre chose. Mais vous perdez l'accès à old_data si vous n'avez qu'un real_index, créez un alias dessus, supprimez l'ancien real_index. L'alias ne pointe plus vers rien.
Jesse Chisholm
@JesseChrisholm Je pense qu'on ne peut pas avoir un "alias qui ne pointe vers rien". Essayez de supprimer real_index, vous verrez que l'alias "un alias vers lui" sera également supprimé.
mgaert
5

Une autre manière différente de renommer ou de modifier les mappages d'un index consiste à réindexer à l'aide de logstash. Voici un exemple de la configuration de logstash 2.1:

input {
  elasticsearch {
   hosts => ["es01.example.com", "es02.example.com"]
   index => "old-index-name"
   size => 500
   scroll => "5m"
  }
}
filter {

 mutate {
  remove_field => [ "@version" ]
 }

 date {
   "match" => [ "custom_timestamp", "MM/dd/YYYY HH:mm:ss" ]
   target => "@timestamp"
 }

}
output {
 elasticsearch {
   hosts => ["es01.example.com", "es02.example.com" ]
   manage_template => false
   index => "new-index-name"
 }
}
Gabriel Rosca
la source
4
Vous dites donc que la meilleure façon de réindexer un index Elasticsearch est d'installer Logstash, puis de l'utiliser pour réindexer? Cela semble un peu exagéré, surtout si vous ne voulez pas / n'utilisez pas Logstash ...
M. Justin
Le seul problème dans la réponse est la partie "La meilleure". Je dirais "Une autre façon". A part ça, c'est une bonne réponse.
Robert
-5

Juste au cas où quelqu'un en aurait encore besoin. La manière réussie, et non officielle, de renommer les index est:

  1. Fermer les index qui doivent être renommés
  2. Renommez les dossiers des index dans tous les répertoires de données des nœuds maître et de données.
  3. Rouvrir les anciens index fermés (j'utilise le plugin kofp). Les anciens index seront rouverts mais resteront non attribués. Les nouveaux index apparaîtront à l'état fermé
  4. Rouvrir de nouveaux index
  5. Supprimer les anciens index

Si vous obtenez cette erreur «le nom du répertoire d'index suspendu est», supprimez le dossier d'index dans tous les nœuds maîtres (pas les nœuds de données) et redémarrez l'un des nœuds de données.

Anh Le
la source
2
Fortement déconseillé par Elastic. Assurez-vous d'avoir des sauvegardes si vous le faites.
lucabelluccini
Je ne comprends pas où le nom de l'index apparaît dans le répertoire de données. Quand je regarde dans / var / lib / elasticsearch / nodes / 0 / indices / les noms des répertoires sont générés aléatoirement, comme "1aS4RusHSYWLdt-Wx7NnBw" (Elasticsearch version 5.6.3)
Johan Boulé
1
@ JohanBoulé, cette méthode n'est plus valable depuis la version 5 d'Elasticsearch.
Anh Le
@lucabelluccini, d'accord. Mieux vaut les laisser tels quels et utiliser des alias.
Anh Le