需求
ES集群Cluster_A里的數據(某個索引或某幾個索引),需要遷移到另外一個ES集群Cluster_B中。
環境
Linux:Centos7 / Centos6.5/ Centos6.4
Elastic:5.2.0
總結的方法
-
查詢並導出數據
-
拷貝ES物理目錄/文件
-
ES快照數據備份和恢復
遷移方法
分別進行以上方法的詳細介紹:
查詢並導出數據
理論
通過ES提供的查詢API,寫各種程序,把數據導出csv,或者把數據查詢出來,直接入庫到新的ES集群中。
實踐
#coding=utf-8
import os
import sys
import pyes
index_list = [
["index_A", "type_A"],
["index_B", "type_B"],
["index_C", "type_C"],
]
ES_URL = "http://192.168.1.1:9200/"
NEW_ES_URL = "http://192.168.2.1:8200/"
def main():
for _index, _type in index_list:
conn = pyes.es.ES(ES_URL)
search = pyes.query.MatchAllQuery().search(bulk_read=10000)
hits = conn.search(search, _index, _type, scan=True, scroll="30m", model=lambda _,hit: hit)
conn2 = pyes.es.ES(NEW_ES_URL)
count = 0
for hit in hits:
conn2.index(hit['_source'], _index, _type, hit['_id'], bulk=True)
count += 1
if count % 10000 == 0:
print count
conn2.flush()
conn2.flush()
conn2 = None
conn = None
if __name__ == '__main__':
main()
注意事項
-
需要安裝python的pyes模塊,注意pyes的版本,此處的版本為:pyes.0.20.1
-
用了查詢ES的scroll方式,也有一種直接通過ES的DSL查詢語句用分頁from和size查詢,但是ES的分頁查詢到了千萬級別之后,from就會慢的出奇,甚至報錯,不信的同學去嘗試吧,等着功虧一簣….
-
客戶現場的數據級別是物理存儲大概在5T(一個副本),條數大概1百億。現場使用該方法親測之后,未解決ES遷移的問題。pyes在約到后面查詢越慢,最后ES報錯…..
總結
- 百萬、千萬級別條數的數據,可以嘗試該方法。
拷貝ES物理目錄/文件
理論
ES的文件存在磁盤中,把物理文件一模一樣拷貝一份到新的集群環境中,達到數據遷移的效果。
實踐
1. 找到ES的存儲目錄,一般可以到elasticsearch.yml中找到path.data的配置
2. 集群下一般會有多個節點,所以ES的存儲目錄也就有多個
3. 一般ES的存儲目錄下,會存儲一個集群名字一樣的文件夾,需要拷貝的就是這個文件夾.
4. 環境如下:
舊集群:
集群名字:Cluster_A
分片數:6
機器A:一個節點 192.168.1.1
node0 數據存儲目錄:/opt/data1,/opt/data2
機器B:三個節點 192.168.1.2
node1 數據存儲目錄:/opt/data1,/opt/data2
node2 數據存儲目錄:/opt/data3,/opt/data4
node3 數據存儲目錄:/opt/data5,/opt/data6
新的集群:
集群名字:Cluster_A
分片數:6
機器A:一個節點 192.168.2.1
node0 數據存儲目錄:/opt/data1,/opt/data2
機器B:三個節點 192.168.2.2
node1 數據存儲目錄:/opt/data1,/opt/data2
node2 數據存儲目錄:/opt/data3,/opt/data4
node3 數據存儲目錄:/opt/data5,/opt/data6
5. 遷移代碼如下:
新集群機器A:192.168.2.1如下操作
scp –r root@192.168.1.1:/opt/data1/Cluster_A /opt/data1/
scp –r root@192.168.1.1:/opt/data2/Cluster_A /opt/data2/
新集群機器B:192.168.2.2如下操作
scp –r root@192.168.1.2:/opt/data1/Cluster_A /opt/data1/
scp –r root@192.168.1.2:/opt/data2/Cluster_A /opt/data2/
scp –r root@192.168.1.2:/opt/data3/Cluster_A /opt/data3/
scp –r root@192.168.1.2:/opt/data4/Cluster_A /opt/data4/
scp –r root@192.168.1.2:/opt/data5/Cluster_A /opt/data5/
scp –r root@192.168.1.2:/opt/data6/Cluster_A /opt/data6/
ES快照數據備份和恢復
理論
使用ES官網提供的快照備份方法,將舊集群ES的索引進行備份,拷貝備份出來的所有文件,在新的集群中進行恢復。
官網寫的非常簡單:先創建倉庫(repository),再往倉庫里添加一個快照(snapshot),查看備份狀態,That’s all。但是實踐需要麻煩很多了。
實踐
1. 舊的集群備份出來的東西,需要拷貝到新集群機器上。解決兩個問題:一是舊集群沒有足夠的空間存儲這些東西;二是反正備份出來都需要拷貝到新的集群中。此處想到一個方法,將新集群機器的目錄遠程Mount到舊集群機器上。
2. 掛載目錄,2.1)和2.2)可以任選一種方式
3. 使用sshfs進行掛載:
// 在每台機器上安裝sshfs
yum install fuse sshfs
// 每台機器上創建Mount共享目錄
mkdir /opt/backup_es
// 舊集群的每台機器上掛載共享目錄(分別掛載了新機器的/opt/data07目錄到/opt/backup_es)
sshfs root@192.168.2.1:/opt/data07 /opt/backup_es -o allow_other
sshfs root@192.168.2.2:/opt/data07 /opt/backup_es -o allow_other
// 測試運行ES的用戶是否有對共享目錄的寫權限
sudo -u elastic touch /opt/backup_es
// 在舊機器上將共享目錄的權限付給ES的運行用戶
chown elastic:elastic -R /opt/backup_es
2. 使用Mount nfs進行掛載:
// 在新集群的機器上(192.168.2.1, 192.168.2.2)添加共享的文件夾和客戶端可以訪問的IP地址
vi /etc/exports
/opt/data07 192.168.1.1(rw,no_root_squash)
/opt/data07 192.168.1.2(rw,no_root_squash)
// 查看共享文件夾和
exportfs -rv
// 重啟啟動新集群機器的NFS服務
services nfs restart
// 舊集群的每台機器上創建共享目錄
mkdir /opt/backup_es
// 舊集群機器上進行Mount掛載
mount -t nfs 192.168.2.1:/opt/data07 /opt/backup_es
mount -t nfs 192.168.2.2:/opt/data07 /opt/backup_es
// 在舊機器上將共享目錄的權限付給ES的運行用戶
chown elastic:elastic -R /opt/backup_es
3. 創建ES倉庫
// 創建ES倉庫my_backup
http://192.168.1.1:9200/_plugin/head/的復合查詢,通過PUT進行發送請求:
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/opt/backup_es",
"compress": true
}
}
// 查看倉庫的狀態
http://192.168.1.1:9200/_snapshot
4. 創建快照備份
// 針對具體的index創建快照備份(可以指定1個快照1個索引,或1個快照多個索引)
// 后面會依據快照的名稱來進行恢復
http://192.168.1.1:9200/
PUT _snapshot/my_backup/snapshot_name_A
{
"indices": "index_A, index_B"
}
成功之后,備份已經異步開始了。
5. 查看備份的狀態
// 查看備份狀態
http://192.168.1.1:9200/_snapshot/my_backup/snapshot_name_A/_status
細心的同學會看到ES會同時進行幾個分片的備份,而且顯示備份的數據情況。
有心的同學會看到,舊集群上共享的兩個目錄/opt/backup_es會均分備份出來的數據。這一點ES還是比較強大的,贊一個。應該還可以指定多個目錄(作者沒有試過,但是應該也是OK的,這樣就可以掛載多個目錄,解決磁盤空間不足的問題了)
6. 最后,就是等,直至所有的的備份都完成。
備份完成后,查看舊集群每台機器的/opt/backup_es目錄,查看備份出的東東。
取消掛載
7. 在新集群中恢復
// 在新集群每台機器上將共享目錄的權限付給ES的運行用戶
chown elastic:elastic -R /opt/data07
// 停止ES,設置elasticsearch.yml的參數
path.repo: /opt/data07
// 啟動ES,在新集群創建倉庫
http://192.168.2.1:9200/_plugin/head/的復合查詢,通過PUT進行發送請求:
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/opt/data07",
"compress": true
}
}
8. 在新集群中恢復數據
// 使用RESTful API進行備份的恢復
http://192.168.1.1:9200/
POST
_snapshot/my_backup/snapshot_name_A/_restore
// 查看恢復的狀態
http://192.168.1.1:9200/
GET
_snapshot/my_backup/snapshot_name_A/_status
9. 等,直至恢復完成。
注意事項
-
索引很大,需要有足夠的空間存儲備份出來的數據,掛載磁盤和設置path.repo來解決該問題。
-
在簡歷倉庫的時候,會報錯,找不到快照目錄/opt/backup_es
需要在elasticsearch.yml中設置path.repo: /opt/backup_es -
掛載的磁盤需要賦權限,讓ES的用戶能讀寫。Sshfs的時候加上 -oallow_other;Mount的時候需要對目錄進行賦權限chown
-
Mount nfs的時候需要注意配置:vi /etc/exports
/opt/data07192.168.1.1(rw,no_root_squash)
/opt/data07192.168.1.2(rw,no_root_squash)
-
新集群中如果有索引和備份出來的索引有沖突(索引已存在),恢復不成功。
解決:可以將舊的索引重命名,然后導入新集群中。導入成功后,將兩個索引建立一個別名。 -
恢復期間,整個集群會變成紅色(集群不可用),最好半夜的時候進行。