太強了!分散式Elasticsearch叢集資料遷移企業案例
01—背景介紹在現代企業架構中,資料的可靠性、安全性以及高效遷移成為了運維管理和業務連續性的核心考量因素。Elasticsearch作為一種高效能、分散式、開源的搜尋引擎和資料分析引擎,廣泛應用於日誌分析、實時搜尋、商業智慧等領域。隨著資料的增長和業務需求的變化,資料遷移在生產環境中顯得尤為重要,比如進行叢集擴容、資料分割槽調整、跨地域遷移等場景。Elasticsearch自身內建了一套強大的資料備份與恢復機制,即Snapshot(快照)和Restore(恢復)功能。Snapshot API允許管理員在指定的Repository(倉庫)中建立資料的只讀快照,這個過程對正在執行的叢集影響較小,且可以實現增量備份,大大提升了備份效率和資源利用率。Repository可以基於多種儲存後端,如共享檔案系統(如NFS)、雲端儲存服務(如Amazon S3、Azure Blob Storage等)。當需要進行資料遷移時,Snapshot和Restore功能提供了無縫的資料遷移途徑。首先,透過Snapshot API在源叢集上建立一個或多個索引的快照,並將其儲存在共享的Repository中。然後,在目標叢集上註冊相同的Repository,並透過Restore API將快照恢復到目標叢集。這種方式不僅能保證資料的完整性,還允許靈活選擇遷移的資料範圍和時間點,極大地方便了運維人員在保持服務連續性的同時進行資料遷移操作。綜上所述,Elasticsearch自帶的Snapshot和Restore機制是進行資料遷移的理想工具,它既能滿足大規模資料遷移的需求,又能確保資料遷移過程中服務的穩定性及資料一致性,從而在實際應用中得到了廣泛的採用和好評。02
—
遷移架構
03
—
環境準備
-
作業系統:CentOS7
-
ES版本:7.10
-
NFS版本:2.5.1
yum
install nfs-utils rpcbind
2. 建立共享目錄並授權
mkdir /mnt/es
chown -R elastic:elastic /mnt/es
3. 修改NFS配置檔案
vi /etc/exports
/mnt/es *(rw,sync,no_root_squash,no_subtree_check)
4. 啟動NFS服務並設定開啟自啟動
systemctl start rpcbind
systemctl start nfs-server
systemctl enable rpcbind
systemctl enable nfs-server
5. 客戶端掛載NFS共享目錄(源目標ES的所有節點都需要配置)
mkdir /mnt/es
chown -R elastic:elastic /mnt/es
mount -t nfs 10.78.23.111:/mnt/es /mnt/es
showmount -e 10.78.23.111
6. 功能驗證,在任意一臺es節點的掛載目錄上建立資料夾並新建檔案,檢視是否同步到所有的es節點上,可藉助ansible的功能批次檢查源和目標上所有的es節點的機器。如下:
mkdir /mnt/es/test/1.txt
echo "123" > /mnt/es/test/.1txt
ls -l /mnt/es/test/1.txt
ansible -i /etc/ansible/hosts es-qy-all -m shell -a 'ls -l /mnt/es/test/1.txt'
備註:須確保源叢集和目標叢集的共享目錄的使用者和使用者組id保持一致,否則資料恢復會有許可權問題。
# 建立使用者組並設定組id為1010
groupadd -g 1010 elastic
#常見使用者id為1010,並加入到組id為1010的車
useradd -u 1010 -g 1010 -G elastic elastic
二、ES叢集和Kibana部署
略(後續會單獨出一期ES分散式叢集的部署教程)
04
—
操作過程
一、全量備份1. 源端叢集插入測試資料(生產環境真實資料遷移可忽略)
1.1 建立索引(測試資料以es_test_index索引為例,生產環境需替換為真實的索引資料)如下:
PUT es_test_index
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"title": {
"type": "text"
},
"content": {
"type": "text"
},
"author": {
"type": "keyword"
}
}
}
}
1.2 插入資料
POST /es_test_index/_bulk
{ "index": { "_id": "1" } }
{ "title": "title1", "content": "a123456", "author": "張三1" }
{ "index": { "_id": "2" } }
{ "title": "title2", "content": "b123456", "author": "張三2" }
{ "index": { "_id": "3" } }
{ "title": "title3", "content": "c123456", "author": "張三3" }
{ "index": { "_id": "4" } }
{ "title": "title4", "content": "d123456", "author": "張三4" }
{ "index": { "_id": "5" } }
{ "title": "title5", "content": "e123456", "author": "張三5" }
1.3 檢視資料
GET es_test_index/_search
"query": {
"match_all": {
}
}
}
2. 源端叢集建立倉庫(Repository)
2.1 在es的配置檔案末尾新增此配置
vim elasticsearch.yml
path.repo: ["/mnt/es"]
2.2 註冊快照儲存庫
PUT _snapshot/es_backup_repo
{
"type": "fs",
"settings": {
"location": "/mnt/es",
"compress": true
}
}
2.3 檢視快照儲存庫
GET _snapshot
3. 源端叢集建立快照(Snapshot)
3.1 建立快照
PUT _snapshot/es_backup_repo/es_snapshot
{
"indices": "es_test_index",
"ignore_unavailable": true,
"include_global_state": true
}
備註:如需備份多個索引SQL如下:
PUT _snapshot/my_backup_repo/my_snapshot?wait_for_completion=true
{
"indices": "my_index1,my_index2",
"ignore_unavailable": true,
"include_global_state": true
}
-
wait_for_completion=true時會一直阻塞直到快照完成,kibana執行時超時為30秒,超時後快照依然會在後。臺執行。
-
ignore_unavailable為建立快照時忽略不存在的索引。
-
indices為指定需要備份的索引(多個用逗號隔開),不指定則會備份所有的es索引庫資料。
3.2 檢視快照資訊
GET _snapshot/es_backup_repo/es_snapshot
3.3 檢視所有快照的全部資訊
GET _snapshot/es_backup_repo/_all?pretty
4. 目標叢集恢復全量資料
4.1 在目標叢集檢視共享的快照備份資料(可藉助ansible批次檢視)
ls -l /mnt/es
4.2 目標節點全部新增倉庫配置
vim elasticsearch.yml
path.repo: ["/mnt/es"]
4.3 目標ES叢集建立快照庫
PUT _snapshot/es_backup_repo
{
"type": "fs",
"settings": {
"location": "/mnt/es",
"compress": true
}
}
4.4 執行資料恢復
POST _snapshot/es_backup_repo/es_snapshot/_restore
5. 在目標叢集驗證資料是恢復
GET es_test_index/_search
{
"query": {
"match_all": {}
}
}
二、增量備份
1. 插入增量資料(生產環境真實資料遷移可忽略)
1.1在上面的es_test_index插入增量資料
POST /es_test_index/_bulk
{ "index": { "_id": "11" } }
{ "title": "title11", "content": "a1123456", "author": "張三11" }
{ "index": { "_id": "12" } }
{ "title": "title12", "content": "b1123456", "author": "張三12" }
{ "index": { "_id": "13" } }
{ "title": "title13", "content": "c1123456", "author": "張三13" }
{ "index": { "_id": "14" } }
{ "title": "title14", "content": "d1123456", "author": "張三14" }
{ "index": { "_id": "15" } }
{ "title": "title15", "content": "e1123456", "author": "張三15" }
1.2 新增一個新的es索引es_test_index_1,並插入增量資料
PUT es_test_index_1
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"title": {
"type": "text"
},
"content": {
"type": "text"
},
"author": {
"type": "keyword"
}
}
}
}
POST /es_test_index_1/_bulk
{ "index": { "_id": "1" } }
{ "title": "title21", "content": "a2123456", "author": "張三21" }
{ "index": { "_id": "2" } }
{ "title": "title22", "content": "b2123456", "author": "張三22" }
{ "index": { "_id": "3" } }
{ "title": "title23", "content": "c2123456", "author": "張三23" }
{ "index": { "_id": "4" } }
{ "title": "title24", "content": "d2123456", "author": "張三24" }
{ "index": { "_id": "5" } }
{ "title": "title25", "content": "e2123456", "author": "張三25" }
2. 源端建立快照(Snapshot)
PUT _snapshot/es_backup_repo/es_snapshot_1
{
"indices": "es_test_index,es_test_index_1",
"ignore_unavailable": true,
"include_global_state": true
}
3. 目標叢集恢復增量資料
3.1 檢視快照資訊
GET _snapshot/es_backup_repo/_all
3.2 關閉目標叢集和源叢集有重複的es索引,目標叢集沒有的無需關閉
POST es_test_index/_close
3.3 目標叢集執行資料恢復
POST _snapshot/es_backup_repo/es_snapshot_1/_restore
3.4 開啟上面關閉的索引
POST es_test_index/_open
4. 目標叢集驗證es資料是否增量同步完成
GET es_test_index/_search
{
"query": {
"match_all": {}
}
}
GET es_test_index_1/_search
{
"query": {
"match_all": {}
}
}
05
—
企業案例1. 定時恢復增量資料到目標叢集
#!/bin/bash
ES_ENDPOINT="http://10.78.23.111:9200"
REPOSITORY_NAME="my_backup_repo"
SNAPSHOT_DATE_FORMAT="daily_snapshot_%Y%m%d"
RESTORE_INDEX_PATTERN=""
# 獲取前一天日期作為快照恢復的時間戳
YESTERDAY=$(date --date='1 day ago' +%Y%m%d)
SNAPSHOT_TO_RESTORE="${SNAPSHOT_DATE_FORMAT//%Y%m%d/$YESTERDAY}"
RESTORED_INDICES_PATTERN="^(${SNAPSHOT_TO_RESTORE}_.*|.*$)" # 匹配快照恢復後的索引名稱
# 檢查昨天的快照是否存在
SNAPSHOT_EXISTS=$(curl -s -u elastic:elastic "${ES_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/${SNAPSHOT_TO_RESTORE}" | jq -e '.snapshots | length > 0')
if [ "$SNAPSHOT_EXISTS" = "true" ]; then
echo "Closing indices that will be affected by the restore process..."
# 獲取將要恢復的索引列表並關閉它們
AFFECTED_INDICES=$(curl -s -u elastic:elastic "${ES_ENDPOINT}/_cat/indices?v&h=index" | grep -E $RESTORED_INDICES_PATTERN)
for INDEX_NAME in $AFFECTED_INDICES; do
curl -X POST "${ES_ENDPOINT}/${INDEX_NAME}/_close" -u elastic:elastic
done
echo "Restoring snapshot ${SNAPSHOT_TO_RESTORE}..."
curl -X POST "${ES_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/${SNAPSHOT_TO_RESTORE}/_restore" \
-u elastic:elastic \
-H 'Content-Type: application/json' \
-d'{
"indices": "*",
"ignore_unavailable": true,
"include_global_state": true
}'
echo "Snapshot ${SNAPSHOT_TO_RESTORE} restored successfully."
echo "Opening the restored indices..."
# 重新開啟已恢復的索引
for INDEX_NAME in $AFFECTED_INDICES; do
curl -X POST "${ES_ENDPOINT}/${INDEX_NAME}/_open" -u elastic:elastic
done
echo "Affected indices opened successfully."
else
echo "Snapshot ${SNAPSHOT_TO_RESTORE} does not exist. Skipping restore process."
fi
exit 0
指令碼獲取方式
後臺回覆:es遷移指令碼
後臺回覆:es遷移指令碼
後臺回覆:es遷移指令碼
MUSIC
♬..♩~ ♫. ♪..
END
推薦閱讀
Jenkins磁碟空間自動清理
ES叢集密碼遺忘?看這篇就夠了給力!利用Python匯出ZABBIX資產指標清單
超實用!利用Nginx實現檔案下載,效率翻倍容器化部署最新版ZABBIX監控系統