Todos os produtos
Search
Central de documentação

Elasticsearch:Migrar dados de um Elasticsearch autogerenciado para o Alibaba Cloud Elasticsearch usando reindex

Última atualização: Aug 21, 2026

Este guia descreve como migrar dados de um cluster Elasticsearch autogerenciado (hospedado no ECS) para uma instância do Alibaba Cloud Elasticsearch por meio da Reindex API. Essa API permite que o cluster de destino extraia dados de um cluster de origem remoto.

Contexto e guia de seleção

A Reindex API é ideal para migrar índices específicos ou volumes de dados pequenos a médios. Escolha a ferramenta adequada conforme a arquitetura da instância e o tamanho dos dados:

Volume de dados / Requisito

Método recomendado

Volume pequeno a médio

Reindex API (Este guia)

Grande volume (> 100 GB)

Advanced guide: Migrate a self-managed Elasticsearch cluster to Alibaba Cloud Elasticsearch using OSS

Filtragem ou transformação de dados

Migrate self-managed Elasticsearch data by using Alibaba Cloud Logstash

Pré-requisitos

  1. Conectividade de rede:

    • A instância ECS (Elasticsearch autogerenciado) e o cluster do Alibaba Cloud Elasticsearch devem estar na mesma Virtual Private Cloud (VPC).

    • Grupo de segurança: O grupo de segurança do ECS deve permitir tráfego de entrada na porta 9200 proveniente dos endereços IP dos nós do Alibaba Cloud Elasticsearch (disponíveis no console do Kibana).

  2. Verificação da arquitetura do cluster: Consulte Basic Information > Control Architecture Type do cluster Alibaba Cloud Elasticsearch para identificar a arquitetura:

  3. Estabilidade: Interrompa a gravação de dados no cluster de origem durante a migração para garantir consistência total dos dados.

Observações de uso

  • Instâncias criadas antes de outubro de 2020 (arquitetura v2) não executam reindexação entre clusters diretamente com instâncias criadas após essa data (arquitetura v3) sem proxy ou PrivateLink. Se as arquiteturas forem diferentes, use o Logstash como intermediário.

  • Ao acessar um Elasticsearch autogerenciado ou um cluster do Alibaba Cloud Elasticsearch por nome de domínio, não use URL que inclua path, como http://host:port/path.

Procedimento

Etapa 1: Estabelecer conectividade de rede (apenas para arquitetura v3)

Se o cluster Alibaba Cloud Elasticsearch usar a arquitetura de controle cloud-native (v3), crie uma conexão privada com o PrivateLink. Para mais informações, consulte Configure a PrivateLink connection.

Etapa 2: Criar índice de destino

Crie o índice no cluster Alibaba Cloud Elasticsearch de destino com os mesmos mappings e configurações da origem.

Script em lote (Python 2.7): Use este script para replicar as estruturas de índice (mappings/shards) do cluster antigo para o novo.

Nota

Neste exemplo, as réplicas são definidas como 0 para acelerar a migração.

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# File name: indiceCreate.py
import sys
import base64
import time
import httplib
import json
## The host of the self-managed Elasticsearch cluster.
oldClusterHost = "old-cluster.com"
## The username for the self-managed Elasticsearch cluster. This can be empty.
oldClusterUserName = "old-username"
## The password for the self-managed Elasticsearch cluster. This can be empty.
oldClusterPassword = "old-password"
## The host of the Alibaba Cloud Elasticsearch cluster. You can obtain it from the Basic Information page of the Alibaba Cloud Elasticsearch instance.
newClusterHost = "new-cluster.com"
## The username for the Alibaba Cloud Elasticsearch cluster.
newClusterUser = "elastic"
## The password for the Alibaba Cloud Elasticsearch cluster.
newClusterPassword = "new-password"
DEFAULT_REPLICAS = 0
def httpRequest(method, host, endpoint, params="", username="", password=""):
    conn = httplib.HTTPConnection(host)
    headers = {}
    if (username != "") :
        'Hello {name}, your age is {age} !'.format(name = 'Tom', age = '20')
        base64string = base64.encodestring('{username}:{password}'.format(username = username, password = password)).replace('\n', '')
        headers["Authorization"] = "Basic %s" % base64string;
    if "GET" == method:
        headers["Content-Type"] = "application/x-www-form-urlencoded"
        conn.request(method=method, url=endpoint, headers=headers)
    else :
        headers["Content-Type"] = "application/json"
        conn.request(method=method, url=endpoint, body=params, headers=headers)
    response = conn.getresponse()
    res = response.read()
    return res
def httpGet(host, endpoint, username="", password=""):
    return httpRequest("GET", host, endpoint, "", username, password)
def httpPost(host, endpoint, params, username="", password=""):
    return httpRequest("POST", host, endpoint, params, username, password)
def httpPut(host, endpoint, params, username="", password=""):
    return httpRequest("PUT", host, endpoint, params, username, password)
def getIndices(host, username="", password=""):
    endpoint = "/_cat/indices"
    indicesResult = httpGet(oldClusterHost, endpoint, oldClusterUserName, oldClusterPassword)
    indicesList = indicesResult.split("\n")
    indexList = []
    for indices in indicesList:
        if (indices.find("open") > 0):
            indexList.append(indices.split()[2])
    return indexList
def getSettings(index, host, username="", password=""):
    endpoint = "/" + index + "/_settings"
    indexSettings = httpGet(host, endpoint, username, password)
    print index + "  The original settings are as follows:\n" + indexSettings
    settingsDict = json.loads(indexSettings)
    ## By default, the number of shards is the same as that of the index in the self-managed Elasticsearch cluster.
    number_of_shards = settingsDict[index]["settings"]["index"]["number_of_shards"]
    ## By default, the number of replicas is 0.
    number_of_replicas = DEFAULT_REPLICAS
    newSetting = "\"settings\": {\"number_of_shards\": %s, \"number_of_replicas\": %s}" % (number_of_shards, number_of_replicas)
    return newSetting
def getMapping(index, host, username="", password=""):
    endpoint = "/" + index + "/_mapping"
    indexMapping = httpGet(host, endpoint, username, password)
    print index + " The original mapping is as follows:\n" + indexMapping
    mappingDict = json.loads(indexMapping)
    mappings = json.dumps(mappingDict[index]["mappings"])
    newMapping = "\"mappings\" : " + mappings
    return newMapping
def createIndexStatement(oldIndexName):
    settingStr = getSettings(oldIndexName, oldClusterHost, oldClusterUserName, oldClusterPassword)
    mappingStr = getMapping(oldIndexName, oldClusterHost, oldClusterUserName, oldClusterPassword)
    createstatement = "{\n" + str(settingStr) + ",\n" + str(mappingStr) + "\n}"
    return createstatement
def createIndex(oldIndexName, newIndexName=""):
    if (newIndexName == "") :
        newIndexName = oldIndexName
    createstatement = createIndexStatement(oldIndexName)
    print "The settings and mapping for the new index " + newIndexName + " are as follows:\n" + createstatement
    endpoint = "/" + newIndexName
    createResult = httpPut(newClusterHost, endpoint, createstatement, newClusterUser, newClusterPassword)
    print "Result of creating the new index " + newIndexName + ": " + createResult
## main
indexList = getIndices(oldClusterHost, oldClusterUserName, oldClusterPassword)
systemIndex = []
for index in indexList:
    if (index.startswith(".")):
        systemIndex.append(index)
    else :
        createIndex(index, index)
if (len(systemIndex) > 0) :
    for index in systemIndex:
        print index + " might be a system index and will not be re-created. Handle it separately if needed."

Etapa 3: Configurar a lista de permissões de reindex remoto

O Alibaba Cloud Elasticsearch exige uma lista de permissões para permitir comunicação remota.

  1. Faça login no console do Alibaba Cloud Elasticsearch.

  2. No painel de navegação à esquerda, selecione Elasticsearch Clusters.

  3. Acesse o cluster de destino.

    1. Na barra de navegação superior, selecione o grupo de recursos e a região do cluster.

    2. Na página Elasticsearch Clusters, localize o cluster e clique em no respectivo ID.

  4. No painel de navegação à esquerda, selecione Configuration and Management > Cluster Configuration.

  5. Na seção YML File Configuration, clique em Modify Configuration à direita.

  1. No painel YML File Configuration, modifique Other Configurations para definir a lista de permissões de reindex. Para mais informações, consulte Configure YML parameters.

    • Arquitetura v2: Especifique uma combinação de host e porta. Exemplo:

      reindex.remote.whitelist: ["10.0.xx.xx:9200","10.0.xx.xx:9200","10.0.xx.xx:9200","10.15.xx.xx:9200","10.15.xx.xx:9200","10.15.xx.xx:9200"]
    • Arquitetura v3: Especifique a combinação do nome de domínio do endpoint e da porta correspondentes à instância. Exemplo:

      ep-bp1hfkx7coy8lvu4****-cn-hangzhou-i.epsrv-bp1zczi0fgoc5qtv****.cn-hangzhou.privatelink.aliyuncs.com:9200
  2. Salve e reinicie o cluster.

Etapa 4: Migrar dados

Selecione o script adequado ao seu cenário de dados.

Cenário A: Migração simples (poucos dados)

Execute este script uma vez para cada índice.

#!/bin/bash
# file:reindex.sh
indexName="Your index name"
newClusterUser="Username for the Alibaba Cloud Elasticsearch cluster"
newClusterPass="Password for the Alibaba Cloud Elasticsearch cluster"
newClusterHost="Host of the Alibaba Cloud Elasticsearch cluster"
oldClusterUser="Username for the self-managed Elasticsearch cluster"
oldClusterPass="Password for the self-managed Elasticsearch cluster"
# The host of the self-managed Elasticsearch cluster must be in the format of [scheme]://[host]:[port], for example, http://10.37.*.*:9200.
oldClusterHost="Host of the self-managed Elasticsearch cluster"
curl -u ${newClusterUser}:${newClusterPass} -XPOST "http://${newClusterHost}/_reindex?pretty" -H "Content-Type: application/json" -d'{
    "source": {
        "remote": {
            "host": "'${oldClusterHost}'",
            "username": "'${oldClusterUser}'",
            "password": "'${oldClusterPass}'"
        },
        "index": "'${indexName}'",
        "query": {
            "match_all": {}
        }
    },
    "dest": {
       "index": "'${indexName}'"
    }
}'

Cenário B: Migração incremental (grande volume de dados com timestamp)

Se houver um campo update_time, use este script de loop para migrar dados em blocos. Isso minimiza o tempo de inatividade ao permitir a sincronização do delta (novas alterações) após a movimentação inicial em massa.

#!/bin/bash
# file: circleReindex.sh
# CONTROLLING STARTUP:
# This is a script for remote reindexing. Requirements:
# 1. The index has been created in the Alibaba Cloud Elasticsearch cluster, or the cluster supports automatic creation and dynamic mapping.
# 2. An IP address whitelist must be configured in the YML file of the Alibaba Cloud Elasticsearch cluster, for example, reindex.remote.whitelist: 172.16.**.**:9200.
# 3. The host must be in the format of [scheme]://[host]:[port].
USAGE="Usage: sh circleReindex.sh <count>
       count: The number of executions. A negative number indicates a loop for incremental execution. A positive number indicates a one-time or multiple executions.
Example:
        sh circleReindex.sh 1
        sh circleReindex.sh 5
        sh circleReindex.sh -1"
indexName="Your index name"
newClusterUser="Username for the Alibaba Cloud Elasticsearch cluster"
newClusterPass="Password for the Alibaba Cloud Elasticsearch cluster"
oldClusterUser="Username for the self-managed Elasticsearch cluster"
oldClusterPass="Password for the self-managed Elasticsearch cluster"
## http://myescluster.com
newClusterHost="Host of the Alibaba Cloud Elasticsearch cluster"
# The host of the self-managed Elasticsearch cluster must be in the format of [scheme]://[host]:[port], for example, http://10.37.*.*:9200.
oldClusterHost="Host of the self-managed Elasticsearch cluster"
timeField="Update time field"
reindexTimes=0
lastTimestamp=0
curTimestamp=`date +%s`
hasError=false
function reIndexOP() {
    reindexTimes=$[${reindexTimes} + 1]
    curTimestamp=`date +%s`
    ret=`curl -u ${newClusterUser}:${newClusterPass} -XPOST "${newClusterHost}/_reindex?pretty" -H "Content-Type: application/json" -d '{
        "source": {
            "remote": {
                "host": "'${oldClusterHost}'",
                "username": "'${oldClusterUser}'",
                "password": "'${oldClusterPass}'"
            },
            "index": "'${indexName}'",
            "query": {
                "range" : {
                    "'${timeField}'" : {
                        "gte" : '${lastTimestamp}',
                        "lt" : '${curTimestamp}'
                    }
                }
            }
        },
        "dest": {
            "index": "'${indexName}'"
        }
    }'`
    lastTimestamp=${curTimestamp}
    echo "The ${reindexTimes}th reindex. The update deadline for this execution is ${lastTimestamp}. Result: ${ret}"
    if [[ ${ret} == *error* ]]; then
        hasError=true
        echo "An exception occurred during this execution. Subsequent operations are interrupted. Please check."
    fi
}
function start() {
    ## If the number is negative, the loop runs continuously.
    if [[ $1 -lt 0 ]]; then
        while :
        do
            reIndexOP
        done
    elif [[ $1 -gt 0 ]]; then
        k=0
        while [[ k -lt $1 ]] && [[ ${hasError} == false ]]; do
            reIndexOP
            let ++k
        done
    fi
}
## main 
if [ $# -lt 1 ]; then
    echo "$USAGE"
    exit 1
fi
echo "Start the reindex operation for the index ${indexName}."
start $1
echo "A total of ${reindexTimes} reindex operations were performed."

Cenário C: Migração incremental (grande volume de dados sem timestamp)

Modifique o código do service upstream para adicionar um campo update_time. Após adicionar o campo, migre primeiro os dados históricos. Em seguida, use o método de migração via scroll descrito em Scenario B: Incremental migration (Large data with timestamp).

#!/bin/bash
# file:miss.sh
indexName="Your index name"
newClusterUser="Username for the Alibaba Cloud Elasticsearch cluster"
newClusterPass="Password for the Alibaba Cloud Elasticsearch cluster"
newClusterHost="Host of the Alibaba Cloud Elasticsearch cluster"
oldClusterUser="Username for the self-managed Elasticsearch cluster"
oldClusterPass="Password for the self-managed Elasticsearch cluster"
# The host of the self-managed Elasticsearch cluster must be in the format of [scheme]://[host]:[port], for example, http://10.37.*.*:9200
oldClusterHost="Host of the self-managed Elasticsearch cluster"
timeField="updatetime"
curl -u ${newClusterUser}:${newClusterPass} -XPOST "http://${newClusterHost}/_reindex?pretty" -H "Content-Type: application/json" -d '{
    "source": {
        "remote": {
            "host": "'${oldClusterHost}'",
            "username": "'${oldClusterUser}'",
            "password": "'${oldClusterPass}'"
        },
        "index": "'${indexName}'",
        "query": {
            "bool": {
                "must_not": {
                    "exists": {
                        "field": "'${timeField}'"
                    }
                }
            }
        }
    },
    "dest": {
       "index": "'${indexName}'"
    }
}'

Perguntas frequentes e solução de problemas

  • P: Ao executar o comando curl, recebo a mensagem de erro {"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}.

    R: Adicione -H "Content-Type: application/json" ao comando curl e tente novamente.

      // Get information about all indexes in the self-managed Elasticsearch cluster. If you do not have permissions, you can remove the "-u user:pass" parameter. oldClusterHost is the host of the self-managed Elasticsearch cluster. Replace it with your actual host.
      curl -u user:pass -XGET http://oldClusterHost/_cat/indices | awk '{print $3}'
      // Based on the returned index list, obtain the settings and mapping of the user index to be migrated. Replace indexName with the name of the user index you want to query.
      curl -u user:pass -XGET http://oldClusterHost/indexName/_settings,_mapping?pretty=true
      // Based on the obtained _settings and _mapping information of the corresponding index, create the corresponding index in the Alibaba Cloud Elasticsearch cluster. You can set the number of replicas to 0 to speed up data synchronization. After the data migration is complete, reset the number of replicas to 1.
      // newClusterHost is the host of the Alibaba Cloud Elasticsearch cluster, testindex is the name of the created index, and testtype is the type of the corresponding index.
      curl -u user:pass -XPUT http://<newClusterHost>/<testindex> -d '{
        "testindex" : {
            "settings" : {
                "number_of_shards" : "5", // Assume that the number of shards for the corresponding index in the self-managed Elasticsearch cluster is 5.
                "number_of_replicas" : "0" // Set the number of replicas for the index to 0.
              }
            },
            "mappings" : { // Assume that the mappings for the corresponding index in the self-managed Elasticsearch cluster are configured as follows.
                "testtype" : {
                    "properties" : {
                        "uid" : {
                            "type" : "long"
                        },
                        "name" : {
                            "type" : "text"
                        },
                        "create_time" : {
                          "type" : "long"
                        }
                    }
               }
           }
       }
    }'
  • P: Como acelerar a migração?

    R:

    • Desative as réplicas: Defina number_of_replicas: 0 no índice de destino antes de iniciar.

    • Desative o refresh: Configure refresh_interval: -1 no índice de destino.

    • Fatiamento: Use o parâmetro slices na Reindex API para paralelizar o processo:

      POST _reindex?slices=5&refresh

      Para mais informações, consulte reindex API.