三種常用的 Elasticsearch 數(shù)據(jù)遷移方案
如果準(zhǔn)備將自建的 elasticsearch 遷移上云,或者的遷移到其他es集群內(nèi),可以根據(jù)自己的業(yè)務(wù)需要選擇合適的遷移方案。??如果業(yè)務(wù)可以停服或者可以暫停寫(xiě)操作?
?,可以使用以下幾種方式進(jìn)行數(shù)據(jù)遷移:
- COS 快照,即?
?Cloud Object Storage?
? - logstash
- elasticsearch-dump
各種遷移方式的對(duì)比如下:
遷移方式 | 適用場(chǎng)景 |
COS 快照 | ? |
logstash | ? |
elasticsearch-dump | ? |
一、COS 快照
基于 COS 快照的遷移方式是使用 ES 的 ??snapshot api?
? 接口進(jìn)行遷移,基本原理就是從源 ES 集群創(chuàng)建索引快照,然后在目標(biāo) ES 集群中進(jìn)行恢復(fù)。通過(guò) snapshot 方式進(jìn)行數(shù)據(jù)遷移時(shí),特別需要注意 ES 的版本問(wèn)題:
目標(biāo) ES 集群的主版本號(hào)(如5.6.4中的5為主版本號(hào))要大于等于源 ES 集群的主版本號(hào)。
1.x 版本的集群創(chuàng)建的快照不能在 5.x 版本中恢復(fù)。
在源 ES 集群中創(chuàng)建 repository
創(chuàng)建快照前必須先創(chuàng)建 repository 倉(cāng)庫(kù),一個(gè) repository 倉(cāng)庫(kù)可以包含多份快照文件,repository 主要有以下幾種類型。
- ?
?fs?
?:共享文件系統(tǒng),將快照文件存放于文件系統(tǒng)中。 - ?
?url?
?:指定文件系統(tǒng)的 URL 路徑,支持協(xié)議:http、https、ftp、file、jar。 - ?
?s3?
?:AWS S3 對(duì)象存儲(chǔ),快照存放于 S3 中,以插件形式支持,安裝該插件請(qǐng)參考 repository-s3[1]。 - ?
?hdfs?
?:快照存放于 hdfs 中,以插件形式支持,安裝該插件請(qǐng)參考 repository-hdfs[2]。 - ?
?cos?
?:快照存放于騰訊云COS對(duì)象存儲(chǔ)中,以插件形式支持,安裝該插件請(qǐng)參考 cos-repository[3]。
如果需要從自建 ES 集群遷移至騰訊云的 ES 集群,可以直接使用 COS 類型倉(cāng)庫(kù)。但需要先在自建 ES 集群上安裝 cos-repository 插件(安裝插件后需要重啟集群才能使用),先把自建 ES 集群中的數(shù)據(jù)先備份到 COS,然后在騰訊云上的 ES 集群中恢復(fù)出來(lái),以完成數(shù)據(jù)的遷移。
如果自建 ES 的集群不方便安裝 cos-repository 插件,但是已經(jīng)安裝 repository-s3 或者 repository-hdfs 插件,則可以先把數(shù)據(jù)備份到 S3 或者 HDFS 中,然后把 S3 或者 HDFS 中備份好的文件上傳到騰訊云 COS 中,之后在騰訊云上的集群中進(jìn)行恢復(fù)。
通過(guò) COS 快照進(jìn)行數(shù)據(jù)遷移時(shí),需要先創(chuàng)建 COS 倉(cāng)庫(kù),您可以通過(guò)如下命令創(chuàng)建倉(cāng)庫(kù):
PUT _snapshot/my_cos_backup
{
"type": "cos",
"settings": {
"app_id": "xxxxxxx",
"access_key_id": "xxxxxx",
"access_key_secret": "xxxxxxx",
"bucket": "xxxxxx",
"region": "ap-guangzhou",
"compress": true,
"chunk_size": "500mb",
"base_path": "/"
}
}
- app_id:騰訊云賬號(hào) APPID。
- access_key_id:騰訊云 API 密鑰 SecretId。
- access_key_secret:騰訊云 API 密鑰 SecretKey。
- bucket:COS Bucket 名字,不帶 appId 后綴的 bucket 名。
- region:COS Bucket 地域,必須與 ES 集群同地域。
- base_path:備份目錄。
在源 ES 集群中創(chuàng)建 snapshot
調(diào)用 snapshot api 創(chuàng)建快照以備份索引數(shù)據(jù),創(chuàng)建快照時(shí)可以指定只對(duì)部分索引進(jìn)行備份,也可以備份所有的索引,具體的 api 接口參數(shù)可以查閱 官方文檔。
備份所有索引
將源 ES 集群中的所有索引備份到 ??my_cos_backup?
?? 倉(cāng)庫(kù)下,并命名為 ??snapshot_1?
?:
PUT _snapshot/my_cos_backup/snapshot_1
這個(gè)命令會(huì)立刻返回,并在后臺(tái)異步執(zhí)行直到結(jié)束。如果希望創(chuàng)建快照命令阻塞執(zhí)行,可以添加 ??wait_for_completion?
? 參數(shù):
PUT _snapshot/my_cos_backup/snapshot_1?wait_for_completion=true
命令執(zhí)行的時(shí)間與索引大小相關(guān)。
備份指定索引
您可以在創(chuàng)建快照的時(shí)候指定要備份的索引:
PUT _snapshot/my_cos_backup/snapshot_2
{
"indices": "index_1,index_2"
}
參數(shù) indices 的值為多個(gè)索引的時(shí)候,需要用?
?,?
?隔開(kāi)且不能有空格。
查看快照狀態(tài)
通過(guò)以下命令檢查快照是否備份完成,返回結(jié)果中的??state?
??字段為??SUCCESS?
?則說(shuō)明快照已經(jīng)備份成功:
GET _snapshot/my_cos_backup/snapshot_1
在目標(biāo) ES 集群中創(chuàng)建 repository
在目標(biāo) ES 集群中創(chuàng)建倉(cāng)庫(kù)和在源 ES 集群中創(chuàng)建倉(cāng)庫(kù)完全相同。
從快照恢復(fù)
將快照中備份的所有索引都恢復(fù)到 ES 集群中:
POST _snapshot/my_cos_backup/snapshot_1/_restore
如果 snapshot_1 包括5個(gè)索引,則這5個(gè)索引都會(huì)被恢復(fù)到 ES 集群中。您還可以使用附加的選項(xiàng)對(duì)索引進(jìn)行重命名。該選項(xiàng)允許您通過(guò)模式匹配索引名稱,并通過(guò)恢復(fù)進(jìn)程提供一個(gè)新名稱。如果您想在不替換現(xiàn)有數(shù)據(jù)的前提下,恢復(fù)舊數(shù)據(jù)來(lái)驗(yàn)證內(nèi)容或進(jìn)行其他操作,則可以使用該選項(xiàng)。從快照里恢復(fù)單個(gè)索引并提供一個(gè)替換的名稱:
POST /_snapshot/my_cos_backup/snapshot_1/_restore
{
"indices": "index_1",
"rename_pattern": "index_(.+)",
"rename_replacement": "restored_index_$1"
}
- indices:只恢復(fù) index_1 索引,忽略快照中存在的其他索引。
- rename_pattern:查找所提供的模式能匹配上的正在恢復(fù)的索引。
- rename_replacement:將匹配的索引重命名成替代的模式。
查看索引恢復(fù)狀態(tài)
您可以通過(guò)調(diào)用 ??_recovery?
? API,查看指定索引恢復(fù)的進(jìn)度:
GET index_1/_recovery
另外可以通過(guò)調(diào)用以下 API,查看指定索引的狀態(tài),返回結(jié)果中 ??status?
?? 為 ??green?
?,則說(shuō)明索引已經(jīng)完全恢復(fù):
GET _cluster/health/index_1
二、logstash
logstash 支持從一個(gè) ES 集群中讀取數(shù)據(jù)然后寫(xiě)入到另一個(gè) ES 集群,因此可以使用 logstash 進(jìn)行數(shù)據(jù)遷移,使用 logstash 進(jìn)行遷移前,需要注意以下幾點(diǎn):
- 需要在和騰訊云上的 ES 集群相同的 VPC 下創(chuàng)建 CVM,部署 logstash,同時(shí)保證該 CVM 能夠訪問(wèn)到源 ES 集群。
- 用于部署 logstash 的 CVM 最好選擇比較高的配置,例如 CPU 為16核,內(nèi)存為32GB。
- logstash 應(yīng)該和目標(biāo) ES 集群的主版本號(hào)相同,例如目標(biāo) ES 集群為6.8.2版本,則 logstash 也需要使用6.8版本。
- 需要特別注意索引
type 的問(wèn)題,因?yàn)?ES 的不同版本對(duì)索引 type 的約束不同,跨大版本遷移 ES 集群時(shí)可能出現(xiàn)因?yàn)樗饕?type
而導(dǎo)致寫(xiě)入目標(biāo)集群失敗等的問(wèn)題。具體可參考 logstash-output-elasticsearch 插件中對(duì) ?
?document_type?
? 參數(shù)的說(shuō)明。
一個(gè)常用的使用 logstash 進(jìn)行跨集群數(shù)據(jù)遷移的配置文件如下:
input {
elasticsearch {
hosts => "1.1.1.1:9200"
index => "*"
docinfo => true
size => 5000
scroll => "5m"
}
}
output {
elasticsearch {
hosts => ["http://2.2.2.2:9200"]
user => "elastic"
password => "your_password"
index => "%{[@metadata][_index]}"
document_type => "%{[@metadata][_type]}"
document_id => "%{[@metadata][_id]}"
}
}
上述配置文件將源 ES 集群的所有索引同步到目標(biāo)集群中,同時(shí)也可以設(shè)置只同步指定的索引,利用 logstash 進(jìn)行遷移的更多功能可查閱 logstash-input-elasticsearch 和 logstash-output-elasticsearch[4]。
三、elasticsearch-dump
elasticsearch-dump 是一款開(kāi)源的 ES 數(shù)據(jù)遷移工具,github 地址[5]。
安裝 elasticsearch-dump
elasticsearch-dump 使用 node.js 開(kāi)發(fā),可使用 npm 包管理工具直接安裝:
npm install elasticdump -g
主要參數(shù)說(shuō)明
--input: 源地址,可為 ES 集群 URL、文件或 stdin,可指定索引,格式為:{protocol}://{host}:{port}/{index}
--input-index: 源 ES 集群中的索引
--output: 目標(biāo)地址,可為 ES 集群地址 URL、文件或 stdout,可指定索引,格式為:{protocol}://{host}:{port}/{index}
--output-index: 目標(biāo) ES 集群的索引
--type: 遷移類型,默認(rèn)為 data,表明只遷移數(shù)據(jù),可選 settings, analyzer, data, mapping, alias如果集群有安全認(rèn)證,可以參照下面的方法使用 reindex 集群鑒權(quán)。在對(duì)應(yīng)的 http 后面,添加 user:password@ 參考樣例 ?
?elasticsearch-dump --input=http://192.168.1.2:9200/my_index --output=http://user:password@192.168.1.2:9200/my_index --type=data?
?。遷移單個(gè)索引
以下操作通過(guò) elasticdump 命令將集群172.16.0.39中的 companydatabase 索引遷移至集群172.16.0.20。
第一條命令先將索引的 settings 先遷移,如果直接遷移 mapping 或者 data 將失去原有集群中索引的配置信息如分片數(shù)量和副本數(shù)量等,當(dāng)然也可以直接在目標(biāo)集群中將索引創(chuàng)建完畢后再同步 mapping 與 data。
elasticdump --input=http://172.16.0.39:9200/companydatabase --output=http://172.16.0.20:9200/companydatabase --type=settings
elasticdump --input=http://172.16.0.39:9200/companydatabase --output=http://172.16.0.20:9200/companydatabase --type=mapping
elasticdump --input=http://172.16.0.39:9200/companydatabase --output=http://172.16.0.20:9200/companydatabase --type=data遷移所有索引
以下操作通過(guò) elasticdump 命令將集群172.16.0.39中的所有索引遷移至集群172.16.0.20。
此操作并不能遷移索引的配置,例如分片數(shù)量和副本數(shù)量,必須對(duì)每個(gè)索引單獨(dú)進(jìn)行配置的遷移,或者直接在目標(biāo)集群中將索引創(chuàng)建完畢后再遷移數(shù)據(jù)。
elasticdump --input=http://172.16.0.39:9200 --output=http://172.16.0.20:9200
四、總結(jié)
- elasticsearch-dump 和 logstash 做跨集群數(shù)據(jù)遷移時(shí),都要求用于執(zhí)行遷移任務(wù)的機(jī)器可以同時(shí)訪問(wèn)到兩個(gè)集群,因?yàn)榫W(wǎng)絡(luò)無(wú)法連通的情況下就無(wú)法實(shí)現(xiàn)遷移。而使用 snapshot 的方式則沒(méi)有這個(gè)限制,因?yàn)?snapshot 方式是完全離線的。因此 elasticsearch-dump 和 logstash 遷移方式更適合于源 ES 集群和目標(biāo) ES 集群處于同一網(wǎng)絡(luò)的情況下進(jìn)行遷移。而需要跨云廠商的遷移,可以選擇使用 snapshot 的方式進(jìn)行遷移,例如從阿里云 ES 集群遷移至騰訊云 ES 集群,也可以通過(guò)打通網(wǎng)絡(luò)實(shí)現(xiàn)集群互通,但是成本較高。
- elasticsearch-dump 工具和 MySQL 數(shù)據(jù)庫(kù)用于做數(shù)據(jù)備份的工具 mysqldump 類似,都是邏輯備份,需要將數(shù)據(jù)一條一條導(dǎo)出后再執(zhí)行導(dǎo)入,所以適合數(shù)據(jù)量小的場(chǎng)景下進(jìn)行遷移。
- snapshot 的方式適合數(shù)據(jù)量大的場(chǎng)景下進(jìn)行遷移。
參考資料
[1]repository-s3: ????https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3.html????
[2]cos-repository: ????https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-hdfs.html????
[3]cos-repository: ????https://github.com/tencentyun/elasticsearch-repository-cos????
[4]repository-s3: ????https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html????
[5]elasticsearch-dump: ????https://github.com/taskrabbit/elasticsearch-dump????