記一次 Docker 中的 ES 數據遷移,使用 Reindex API
- 環境背景
- 需求背景
- 開始遷移
- 確認老 ES 的訪問地址
- 在新 ES 中創建索引的 Mapping (選配)
- 在新 ES 中配置老 ES 的地址
- 開始遷移數據
- 數據驗證
首先聲明,是因為環境限制,沒有辦法使用同步工具,不得已才使用 Reindex API 進行數據同步的。
環境背景
- Linux
- Docker:20
- ElasticSearch:8
需求背景
老的 ES 在 Docker 安裝的時候設置的內存太小,導致數據量過大時查詢直接內存溢出,容器掛掉。原計劃是修改老 ES 的內存配置,奈何最開始安裝的時候沒有進行掛接,進入到容器中也無法修改,就連 Docker 容器的 json 文件都改了,也不行。所以就直接啟動了一個新的 ES 容器,這下把能掛接的目錄都掛到宿主機上,方便后續修改。現在問題來了,之前的數據怎么辦?要么忍痛割愛,等著系統同步,要么數據遷移。果斷選擇后者,誰讓喜歡折騰呢。
開始遷移
確認老 ES 的訪問地址
- 情況1: 因為老 ES 安裝的時候直接使用的主機模式,所以直接用宿主機的IP和對應端口就行。
- 情況2: 沒有使用主機模式,得先查看 Docker 給 ES 分配的 IP 地址。使用
docker inspect <容器ID/名稱>
查看容器信息。找到NetworkSettings -> NetWorks -> bridge -> IPAddress
就可以看到 Docker 給 ES 分配的 IP 地址。
在新 ES 中創建索引的 Mapping (選配)
ES 在數據遷移的時候會自動創建索引,但是 Mapping 不會創建,所以有必要的話可以先在新 ES 中創建索引,并添加 Mapping。如果不需要可以跳過此步驟。
curl -X PUT "http://<ES_HOST>:9200/new_index?pretty" -H 'Content-Type: application/json' -d'
{"settings": { /* 自定義設置 */ },"mappings": { /* 自定義映射 */ }
}
'
在新 ES 中配置老 ES 的地址
編輯 elasticsearch.yml
cluster:remote:old_cluster:seeds: "<源集群容器IP>:9300"
添加配置后,重啟容器生效。重啟命令:docker restart <容器ID/名稱>
開始遷移數據
重啟之后,請求新 ES 地址,開始同步數據
curl -X POST "http://目標ES_HOST:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{"source": {"remote": { "host": "http://源ES_HOST:9200" },"index": "old_index","size": 5000 // 每批遷移文檔數},"dest": { "index": "new_index" }
}
'
如果 ES 有安全認證,需要在 remote 屬性中添加認證屬性;
"remote": {"host": "http://源ES_HOST:9200","headers": { "Authorization": "ApiKey <Base64編碼的API密鑰>" }
}
數據驗證
curl -X GET "http://<ES_HOST>:9200/new_index/_count?pretty" -H 'Content-Type: application/json' -d'
{ "query": { "match_all": {} } }
'
PS:curl 可能用著不舒服,使用 postman 也是可以的,只需要把{}
的內容作為請求的 body傳遞即可,注意改成 JSON 類型。