Panduan ini menjelaskan cara migrasi data dari kluster Elasticsearch yang dikelola sendiri (di-hosting di ECS) ke instans Alibaba Cloud Elasticsearch menggunakan Reindex API. Reindex API memungkinkan kluster tujuan untuk “menarik” data dari kluster sumber jarak jauh.
Latar belakang dan panduan pemilihan
Reindex API ideal untuk migrasi indeks tertentu atau volume data kecil hingga menengah. Bergantung pada arsitektur instans dan ukuran data Anda, pilih alat yang sesuai:
|
Volume Data / Persyaratan |
Metode yang Direkomendasikan |
|
Volume Kecil hingga Menengah |
Reindex API (Panduan ini) |
|
Volume Besar (> 100 GB) |
|
|
Pemfilteran/Transformasi Data |
Migrasi data Elasticsearch yang dikelola sendiri menggunakan Alibaba Cloud Logstash |
Prasyarat
-
Konektivitas jaringan:
-
Instans ECS (Elasticsearch yang dikelola sendiri) dan kluster Alibaba Cloud Elasticsearch harus berada dalam Virtual Private Cloud (VPC) yang sama.
-
Grup keamanan: Grup keamanan ECS harus mengizinkan lalu lintas inbound pada port 9200 dari alamat IP node Alibaba Cloud Elasticsearch (dapat ditemukan di Konsol Kibana).
-
-
Pemeriksaan arsitektur kluster:
Periksa Basic Information > Control Architecture Type pada kluster Alibaba Cloud Elasticsearch Anda untuk melihat arsitekturnya:-
Basic Control Architecture (v2): Di-deploy di VPC Anda. Aksesnya langsung. Lihat Prosedur dalam panduan ini untuk instruksi.
-
Cloud-native Control Architecture (v3): Di-deploy di VPC layanan. Anda harus menggunakan PrivateLink untuk menjembatani jaringan. Lihat Migrasi data Elasticsearch yang dikelola sendiri melalui koneksi privat.
-
-
Stabilitas: Hentikan penulisan data ke kluster sumber selama migrasi untuk memastikan konsistensi data 100%.
Catatan penggunaan
-
Instans yang dibuat sebelum Oktober 2020 (arsitektur v2) tidak dapat langsung melakukan reindex lintas kluster dengan instans yang dibuat setelah Oktober 2020 (arsitektur v3) tanpa menggunakan proxy atau PrivateLink. Jika arsitekturnya berbeda, gunakan Logstash sebagai perantara.
-
Saat Anda menggunakan nama domain untuk mengakses Elasticsearch yang dikelola sendiri atau kluster Alibaba Cloud Elasticsearch, Anda tidak dapat menggunakan URL yang mencakup path, seperti
http://host:port/path.
Prosedur
Langkah 1: Buat konektivitas jaringan (Hanya untuk arsitektur v3)
Jika kluster Alibaba Cloud Elasticsearch Anda menggunakan arsitektur kontrol cloud-native (v3), Anda harus membuat koneksi privat menggunakan PrivateLink. Untuk informasi lebih lanjut, lihat Konfigurasi koneksi PrivateLink.
Langkah 2: Buat indeks tujuan
Anda harus membuat indeks di kluster Alibaba Cloud Elasticsearch tujuan dengan pemetaan dan pengaturan yang sama seperti sumber.
Skrip Batch (Python 2.7): Gunakan skrip ini untuk mereplikasi struktur indeks (pemetaan/shard) dari kluster lama ke yang baru.
Dalam contoh ini, replica diatur ke 0 untuk mempercepat migrasi.
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# Nama file: indiceCreate.py
import sys
import base64
import time
import httplib
import json
## Host kluster Elasticsearch yang dikelola sendiri.
oldClusterHost = "old-cluster.com"
## Username untuk kluster Elasticsearch yang dikelola sendiri. Bisa dikosongkan.
oldClusterUserName = "old-username"
## Password untuk kluster Elasticsearch yang dikelola sendiri. Bisa dikosongkan.
oldClusterPassword = "old-password"
## Host kluster Alibaba Cloud Elasticsearch. Anda bisa mendapatkannya dari halaman Informasi Dasar instans Alibaba Cloud Elasticsearch.
newClusterHost = "new-cluster.com"
## Username untuk kluster Alibaba Cloud Elasticsearch.
newClusterUser = "elastic"
## Password untuk kluster Alibaba Cloud Elasticsearch.
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 + " Pengaturan aslinya adalah sebagai berikut:\n" + indexSettings
settingsDict = json.loads(indexSettings)
## Secara default, jumlah shard sama dengan indeks di kluster Elasticsearch yang dikelola sendiri.
number_of_shards = settingsDict[index]["settings"]["index"]["number_of_shards"]
## Secara default, jumlah replica adalah 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 + " Pemetaan aslinya adalah sebagai berikut:\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 "Pengaturan dan pemetaan untuk indeks baru " + newIndexName + " adalah sebagai berikut:\n" + createstatement
endpoint = "/" + newIndexName
createResult = httpPut(newClusterHost, endpoint, createstatement, newClusterUser, newClusterPassword)
print "Hasil pembuatan indeks baru " + 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 + " kemungkinan merupakan indeks sistem dan tidak akan dibuat ulang. Tangani secara terpisah jika diperlukan."
Langkah 3: Konfigurasi daftar putih reindex jarak jauh
Alibaba Cloud Elasticsearch memerlukan daftar putih untuk mengizinkan komunikasi jarak jauh.
Masuk ke Konsol Alibaba Cloud Elasticsearch.
Di bilah navigasi kiri, pilih Elasticsearch Clusters.
Navigasi ke kluster target.
Di bilah navigasi atas, pilih kelompok sumber daya tempat kluster tersebut berada dan wilayah tempat kluster tersebut berlokasi.
Di halaman Elasticsearch Clusters, temukan kluster tersebut dan klik ID-nya.
-
Di bilah navigasi kiri, pilih .
-
Di bagian YML File Configuration, klik Modify Configuration di sebelah kanan.
-
Di panel YML File Configuration, ubah Other Configurations untuk mengatur daftar putih reindex. Untuk informasi lebih lanjut, lihat Konfigurasi parameter YML.
-
Arsitektur v2: Tentukan kombinasi host dan port. Contoh:
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"] -
Arsitektur v3: Tentukan kombinasi nama domain titik akhir dan port yang sesuai dengan instans. Contoh:
ep-bp1hfkx7coy8lvu4****-cn-hangzhou-i.epsrv-bp1zczi0fgoc5qtv****.cn-hangzhou.privatelink.aliyuncs.com:9200
-
-
Simpan dan restart kluster.
Langkah 4: Migrasi data
Pilih skrip yang sesuai dengan skenario data Anda.
Skenario A: Migrasi sederhana (data kecil)
Jalankan skrip ini sekali untuk setiap indeks.
#!/bin/bash
# file:reindex.sh
indexName="Nama indeks Anda"
newClusterUser="Username untuk kluster Alibaba Cloud Elasticsearch"
newClusterPass="Password untuk kluster Alibaba Cloud Elasticsearch"
newClusterHost="Host kluster Alibaba Cloud Elasticsearch"
oldClusterUser="Username untuk kluster Elasticsearch yang dikelola sendiri"
oldClusterPass="Password untuk kluster Elasticsearch yang dikelola sendiri"
# Host kluster Elasticsearch yang dikelola sendiri harus dalam format [scheme]://[host]:[port], misalnya, http://10.37.*.*:9200.
oldClusterHost="Host kluster Elasticsearch yang dikelola sendiri"
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}'"
}
}'
Skenario B: Migrasi inkremental (Data besar dengan timestamp)
Jika Anda memiliki bidang update_time, gunakan skrip loop ini untuk migrasi data secara bertahap. Ini meminimalkan downtime dengan memungkinkan Anda menyinkronkan "delta" (perubahan baru) setelah pemindahan awal secara massal.
#!/bin/bash
# file: circleReindex.sh
# MENGONTROL STARTUP:
# Ini adalah skrip untuk reindex jarak jauh. Persyaratan:
# 1. Indeks telah dibuat di kluster Alibaba Cloud Elasticsearch, atau kluster mendukung pembuatan otomatis dan pemetaan dinamis.
# 2. Daftar putih alamat IP harus dikonfigurasi di file YML kluster Alibaba Cloud Elasticsearch, misalnya, reindex.remote.whitelist: 172.16.**.**:9200.
# 3. Host harus dalam format [scheme]://[host]:[port].
PENGGUNAAN="Penggunaan: sh circleReindex.sh <jumlah>
jumlah: Jumlah eksekusi. Angka negatif menunjukkan loop untuk eksekusi inkremental. Angka positif menunjukkan eksekusi satu kali atau beberapa kali.
Contoh:
sh circleReindex.sh 1
sh circleReindex.sh 5
sh circleReindex.sh -1"
indexName="Nama indeks Anda"
newClusterUser="Username untuk kluster Alibaba Cloud Elasticsearch"
newClusterPass="Password untuk kluster Alibaba Cloud Elasticsearch"
oldClusterUser="Username untuk kluster Elasticsearch yang dikelola sendiri"
oldClusterPass="Password untuk kluster Elasticsearch yang dikelola sendiri"
## http://myescluster.com
newClusterHost="Host kluster Alibaba Cloud Elasticsearch"
# Host kluster Elasticsearch yang dikelola sendiri harus dalam format [scheme]://[host]:[port], misalnya, http://10.37.*.*:9200.
oldClusterHost="Host kluster Elasticsearch yang dikelola sendiri"
timeField="Bidang waktu pembaruan"
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 "Reindex ke-${reindexTimes}. Batas waktu pembaruan untuk eksekusi ini adalah ${lastTimestamp}. Hasil: ${ret}"
if [[ ${ret} == *error* ]]; then
hasError=true
echo "Terjadi pengecualian selama eksekusi ini. Operasi selanjutnya dihentikan. Harap periksa."
fi
}
function start() {
## Jika angka negatif, loop berjalan terus-menerus.
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 "$PENGGUNAAN"
exit 1
fi
echo "Mulai operasi reindex untuk indeks ${indexName}."
start $1
echo "Total ${reindexTimes} operasi reindex telah dilakukan."
Skenario C: Migrasi inkremental (Data besar tanpa timestamp)
Modifikasi kode layanan hulu untuk menambahkan bidang update_time. Setelah menambahkan bidang tersebut, pertama-tama migrasi data historis. Kemudian, gunakan metode migrasi scroll yang dijelaskan di Skenario B: Migrasi inkremental (Data besar dengan timestamp).
#!/bin/bash
# file:miss.sh
indexName="Nama indeks Anda"
newClusterUser="Username untuk kluster Alibaba Cloud Elasticsearch"
newClusterPass="Password untuk kluster Alibaba Cloud Elasticsearch"
newClusterHost="Host kluster Alibaba Cloud Elasticsearch"
oldClusterUser="Username untuk kluster Elasticsearch yang dikelola sendiri"
oldClusterPass="Password untuk kluster Elasticsearch yang dikelola sendiri"
# Host kluster Elasticsearch yang dikelola sendiri harus dalam format [scheme]://[host]:[port], misalnya, http://10.37.*.*:9200
oldClusterHost="Host kluster Elasticsearch yang dikelola sendiri"
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}'"
}
}'
FAQ dan troubleshooting
-
T: Saat saya menjalankan perintah curl, muncul pesan error
{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}.J: Tambahkan
-H "Content-Type: application/json"ke perintah curl dan coba lagi.// Dapatkan informasi tentang semua indeks di kluster Elasticsearch yang dikelola sendiri. Jika Anda tidak memiliki izin, Anda dapat menghapus parameter "-u user:pass". oldClusterHost adalah host kluster Elasticsearch yang dikelola sendiri. Ganti dengan host aktual Anda. curl -u user:pass -XGET http://oldClusterHost/_cat/indices | awk '{print $3}' // Berdasarkan daftar indeks yang dikembalikan, dapatkan pengaturan dan pemetaan indeks pengguna yang akan dimigrasi. Ganti indexName dengan nama indeks pengguna yang ingin Anda kueri. curl -u user:pass -XGET http://oldClusterHost/indexName/_settings,_mapping?pretty=true // Berdasarkan informasi _settings dan _mapping yang diperoleh dari indeks yang sesuai, buat indeks yang sesuai di kluster Alibaba Cloud Elasticsearch. Anda dapat mengatur jumlah replica ke 0 untuk mempercepat sinkronisasi data. Setelah migrasi data selesai, atur ulang jumlah replica ke 1. // newClusterHost adalah host kluster Alibaba Cloud Elasticsearch, testindex adalah nama indeks yang dibuat, dan testtype adalah tipe indeks yang sesuai. curl -u user:pass -XPUT http://<newClusterHost>/<testindex> -d '{ "testindex" : { "settings" : { "number_of_shards" : "5", // Asumsikan jumlah shard untuk indeks yang sesuai di kluster Elasticsearch yang dikelola sendiri adalah 5. "number_of_replicas" : "0" // Atur jumlah replica untuk indeks menjadi 0. } }, "mappings" : { // Asumsikan pemetaan untuk indeks yang sesuai di kluster Elasticsearch yang dikelola sendiri dikonfigurasi sebagai berikut. "testtype" : { "properties" : { "uid" : { "type" : "long" }, "name" : { "type" : "text" }, "create_time" : { "type" : "long" } } } } } }' -
T: Bagaimana cara mempercepat migrasi?
J:
-
Nonaktifkan replica: Atur
number_of_replicas: 0pada indeks tujuan sebelum memulai. -
Nonaktifkan refresh: Atur
refresh_interval: -1pada indeks tujuan. -
Pemotongan (Slicing): Gunakan parameter
slicesdalam Reindex API untuk memparalelkan proses:POST _reindex?slices=5&refreshUntuk informasi lebih lanjut, lihat reindex API.
-