como renomear um índice em um cluster?

110

Preciso renomear vários índices em um cluster (seus nomes devem ser alterados, não posso usar aliases ).

Vi que não há formas suportadas de fazer isso, o mais próximo que encontrei é renomear o diretório do índice , tentei em um cluster.

O aglomerado tem 3 máquinas A, Be Ce os fragmentos são replicados em cada um deles. Desliguei o elasticsearch em A, renomeei /var/lib/elasticsearch/security/nodes/0/indices/oldindexnamepara /var/lib/elasticsearch/security/nodes/0/indices/newindexnamee reiniciei A.

O estado do cluster era amarelo e a elasticsearch estava fazendo mágica para restaurar um estado correto. Depois de algum tempo acabei com

  • oldindexnameestando disponível e totalmente replicado (recuperado de Be Ceu acho)
  • newindexname estando disponível (posso pesquisá-lo), mas o plug-in principal mostra que seus fragmentos estão em um estado "Não atribuído" e que estão acinzentados (não replicados)

Durante a recuperação security.logmostrou a seguinte mensagem:

[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

Embora newindexnameseja pesquisável, certamente não está em um estado normal.

Eu voltei ao estado anterior excluindo newindexname. O cluster está de volta ao verde sem nenhuma entrada "Não atribuída".

Dado isso, como posso renomear oldindexnamepara newindexnameem um cluster?

Nota: a solução definitiva que tenho em mente é a de rolagem-cópia oldindexem newindexe excluir oldindexdepois. Isso vai levar tempo, então se houver uma solução mais direta, seria ótimo.

WoJ
fonte

Respostas:

19

A partir do ElasticSearch 7.4, o melhor método para renomear um índice é copiá-lo usando a API Clone Index recém-introduzida e , em seguida, excluir o índice original usando a API Delete Index .

A principal vantagem da API Clone Index sobre o uso da API Snapshot ou da API Reindex para o mesmo propósito é a velocidade, uma vez que a API Clone Index vincula segmentos do índice de origem ao índice de destino, sem reprocessar nenhum de seu conteúdo (em sistemas de arquivos que suportam hardlinks, obviamente; caso contrário, os arquivos são copiados no nível do sistema de arquivos, que ainda é muito mais eficiente que as alternativas). O índice clone também garante que o índice de destino seja idêntico em todos os pontos ao índice de origem (ou seja, não há necessidade de copiar manualmente as configurações e mapeamentos, ao contrário da abordagem Reindex) e não requer a configuração de um diretório de instantâneo local .

Nota lateral: embora este procedimento seja muito mais rápido do que as soluções anteriores, ainda implica tempo de inatividade. Existem casos de uso reais que justificam a renomeação de índices (por exemplo, como uma etapa em uma divisão, redução ou fluxo de trabalho de backup), mas renomear índices não deve fazer parte das operações do dia a dia. Se o seu fluxo de trabalho requer renomeação de índice frequente, você deve considerar o uso de aliases de índices .

Aqui é um exemplo de uma sequência completa de operações para mudar o nome índice source_indexa target_index. Ele pode ser executado usando algum console específico do ElasticSearch, como o integrado no Kibana . Veja esta essência para uma versão alternativa deste exemplo, usando em curlvez de um console do 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
fonte
163

Você pode usar REINDEX para fazer isso.

Reindex não tenta configurar o índice de destino. Ele não copia as configurações do índice de origem. Você deve configurar o índice de destino antes de executar uma ação _reindex, incluindo a configuração de mapeamentos, contagens de fragmentos, réplicas, etc.

  1. Primeiro copie o índice para um novo nome
POST /_reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}
  1. Agora exclua o índice
DELETE /twitter
reto
fonte
Embora isso exija espaço para ambos os índices (temporariamente), isso é simples e totalmente no servidor - então, parece ser a melhor solução até agora (embora o documento avise sobre um status 'experimental'). Obrigado.
WoJ
2
Isso funciona se o mapeamento funcionou _source: {enabled: false}?
Harald
2
@Harald Não, _reindexusa _sourcecomo dados do documento original.
Agop
6
Isso não copiará o mapeamento de twitterpara new_twitter, até onde eu sei.
Nick
3
Concordo com a solução de _reindex, mas a questão deve ser alterada. Reindexar não é simplesmente renomear. Pode até alterar a forma como os dados são indexados.
lucabelluccini
62

Para renomear seu índice, você pode usar o módulo Elasticsearch Snapshot.

Primeiro, você deve tirar um instantâneo do seu índice. Ao restaurá-lo, você pode renomear o seu índice.

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

rename_replacement: -Novo indexname no qual você deseja fazer backup de seus dados.

Krishna Kumar
fonte
4
Caramba, isso é incrivelmente útil. Obrigado!
Chris Cogdon
1
Muito melhor do que a solução aceita! Na verdade, esta é uma cópia binária do índice, portanto, não há risco de perder nada e não precisa _sourceser habilitada no índice. Eu mudei o nome de alguns índices multi-TB desta forma sem problemas.
Jaqueta
2
@Jacket - Fico feliz em saber que minha resposta realmente o ajuda.
Krishna Kumar,
1
Eu concordo, solução muito melhor, sem problemas de perda de dados, muito MAIS RÁPIDA também para grandes índices do que reindexação
Romain Hautefeuille
1
ele retém o mapeamento?
Amogh Mishra
5

Como tal, não existe um método direto para copiar ou renomear o índice no ES (eu pesquisei extensivamente por meu próprio projeto)

No entanto, uma opção muito fácil é usar uma ferramenta de migração popular [Elastic-Exporter].

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

[PS: este não é o meu blog, apenas tropecei e achei bom]

Assim, você pode copiar o índice / tipo e, em seguida, excluir o antigo.

preguiçoso
fonte
O link não funciona mais. Qualquer outro lugar em que possamos encontrar ou ter essa informação?
elachell
5

Se você não puder REINDEX, uma solução alternativa é usar aliases . Da documentação oficial :

APIs em elasticsearch aceitam um nome de índice ao trabalhar em um índice específico e vários índices quando aplicável. A API de aliases de índice permite alias a um índice com um nome, com todas as APIs convertendo automaticamente o nome do alias no nome do índice real. Um alias também pode ser mapeado para mais de um índice e, ao especificá-lo, o alias se expandirá automaticamente para os índices de aliases. Um alias também pode ser associado a um filtro que será aplicado automaticamente ao pesquisar e rotear valores. Um alias não pode ter o mesmo nome de um índice.

Esteja ciente de que esta solução não funciona se você estiver usando o recurso Mais como este. https://github.com/elastic/elasticsearch/issues/16560

Leo
fonte
1
I need to rename several indexes in a cluster (their name must be changed I cannot use aliases).Por @WoJ
Thales P
O alias do motivo não funciona : o uso alias exige que você planeje com antecedência e crie o nome do índice original as an aliaspara um índice real. Em seguida, você pode criar um novo nome de alias e reutilizar o nome de alias antigo para outra coisa. Mas você perde o acesso a old_data se você tem apenas um real_index, faça um alias para ele, delete o antigo real_index. O alias agora não aponta para nada.
Jesse Chisholm
@JesseChrisholm Acho que não se pode ter um "alias que não aponta para nada". Tente remover real_index, você verá que o alias "um alias para ele" também será removido.
março
5

Outra maneira diferente de conseguir renomear ou alterar os mapeamentos de um índice é reindexar usando logstash. Aqui está um exemplo da configuração do 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
fonte
4
Você está dizendo que a melhor maneira de reindexar um índice Elasticsearch é instalar o Logstash e usá-lo para reindexar? Parece um pouco exagero, especialmente se você não quiser / usar o Logstash ...
M. Justin
O único problema na resposta é a parte "A melhor". Eu diria "De outra forma". Fora isso, é uma boa resposta.
Robert
-5

Para o caso de alguém ainda precisar. A maneira bem-sucedida, não oficial, de renomear índices é:

  1. Fechar índices que precisam ser renomeados
  2. Renomeie as pastas dos índices em todos os diretórios de dados dos nós mestre e de dados.
  3. Reabra os índices fechados antigos (eu uso o plugin kofp). Os índices antigos serão reabertos, mas permanecerão sem atribuição. Novos índices aparecerão em estado fechado
  4. Reabrir novos índices
  5. Excluir índices antigos

Se acontecer de você receber este erro "dangled index directory name is", remova a pasta de índice em todos os nós principais (não nos nós de dados) e reinicie um dos nós de dados.

Anh Le
fonte
2
Fortemente desencorajado por Elastic. Certifique-se de ter backups se fizer isso.
lucabelluccini
Não entendo onde o nome do índice aparece no diretório de dados. Quando eu olho em / var / lib / elasticsearch / nodes / 0 / indices / os nomes dos diretórios são gerados aleatoriamente, como "1aS4RusHSYWLdt-Wx7NnBw" (Elasticsearch versão 5.6.3)
Johan Boulé
1
@ JohanBoulé, este método não é mais válido desde a versão 5 do Elasticsearch.
Anh Le
@lucabelluccini, concordou. Melhor deixá-los como estão e usar apelidos.
Anh Le