太強了!分散式Elasticsearch叢集資料遷移企業案例

技术颜良發表於2024-04-04

太強了!分散式Elasticsearch叢集資料遷移企業案例


Linux運維之旅
專注分享運維實用技術,內容不限於Linux系統運維、自動化工具、監控工具、日誌採集、容器技術、測試工具、python、GO等技術分享
20篇原創內容

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

一、NFS服務部署1. 安裝NFS服務軟體包

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

圖片
Linux運維之旅
專注分享運維實用技術,內容不限於Linux系統運維、自動化工具、監控工具、日誌採集、容器技術、測試工具、python、GO等技術分享
20篇原創內容
圖片

推薦閱讀

圖片
Jenkins磁碟空間自動清理
ES叢集密碼遺忘?看這篇就夠了給力!利用Python匯出ZABBIX資產指標清單
超實用!利用Nginx實現檔案下載,效率翻倍容器化部署最新版ZABBIX監控系統
Elasticsearch · 目錄
上一篇ES叢集密碼遺忘?看這篇就夠了
閱讀 116

相關文章