白话Elasticsearch72_利用HDFS备份与恢复ES生产集群的数据
文章目錄
- 概述
- 官方指導
- hadoop hdfs分布式文件存儲系統介紹
- hdfs環境搭建
- 基于snapshot+hdfs進行數據備份
- 0、es集群數據備份的必要性
- 1、ES數據備份儲存如何選擇?
- 2、創建備份倉庫
- 方式一 利用fs(共享文件系統)創建和查詢倉
- 方式二:基于hdfs創建倉庫(推薦)
- (1)安裝repository-hdfs的插件
- (2)創建hdfs倉庫
- (3)驗證倉庫
- 3、對索引進行snapshotting備份
- (1)對所有open的索引進行snapshotting備份
- (2)對指定的索引進行snapshotting備份
- 4、查看snapshot備份列表
- 5、刪除snapshot備份
- 6、監控snapshotting的進度
- 7、取消snapshotting備份過程
- 基于snapshot+hdfs+restore進行數據恢復
- 1、基于snapshot的數據恢復
- 2、監控restore的進度
- 3、取消恢復過程
概述
繼續跟中華石杉老師學習ES,第72篇
課程地址: https://www.roncoo.com/view/55
本篇博文不會涉及非常詳細的操作步驟截圖,僅把備份與恢復的關鍵步驟記錄,等后續有真正的使用場景的時候,再來實操。
官方指導
備份你的集群 : https://www.elastic.co/guide/cn/elasticsearch/guide/current/backing-up-your-cluster.html
主要是利用 ES本身提供的 snapshot API 。
hadoop hdfs分布式文件存儲系統介紹
簡單介紹下Hadoop生態圈中非常常用的幾個組件:
-
hdfs,提供的是分布式的文件存儲,數據存儲
-
hbase,提供的是分布式的NoSQL數據庫,基于hdf
-
yarn,提供的是分布式的資源調度
-
mapreduce,提供的是分布式的計算引擎,跑在yarn上面的,由yarn去做資源調度
-
hive,提供的是分布式的數據倉庫引擎,基于mapreduce
hdfs環境搭建
這部分,網上教程很多,不細說了。 搭建一個3個節點的Hadoop集群。
這里用的版本為 2.7.1
1、將hadoop-2.7.1.tar.gz 上傳到/usr/local目錄下。
2、將hadoop包進行解壓縮:tar -zxvf hadoop-2.7.1.tar.gz
3、對hadoop目錄進行重命名:mv hadoop-2.7.1 hadoop
4、配置hadoop相關環境變量
生效
source .bashrc5、在/usr/local目錄下創建data目錄
6、修改配置文件
core-site.xml
<property><name>fs.defaultFS</name><value>hdfs://elasticsearch01:9000</value> </property>hdfs-site.xml
<property><name>dfs.namenode.name.dir</name><value>/usr/local/data/namenode</value> </property> <property><name>dfs.datanode.data.dir</name><value>/usr/local/data/datanode</value> </property>yarn-site.xml
<property><name>yarn.resourcemanager.hostname</name><value>elasticsearch01</value> </property>value為master節點 。
mapred-site.xml
<property><name>mapreduce.framework.name</name><value>yarn</value> </property>配置 slaves文件,沒有的話新建,寫入
elasticsearch01 elasticsearch02 elasticsearch03在另外兩臺機器上部署
1、使用scp命令將elasticsearch01上面的hadoop安裝包和.bashrc配置文件都拷貝過去。
2、要記得對.bashrc文件進行source,以讓它生效。
3、記得在另外兩臺機器的/usr/local目錄下創建data目錄。
啟動hdfs集群
su elasticsearch chown -R elasticsearch /usr/local/hadoop chown -R elasticsearch /usr/local/data1、格式化namenode:在elasticsearch01上執行以下命令hdfs namenode -format
2、啟動hdfs集群:start-dfs.sh
3、驗證啟動是否成功:jps、50070端口
基于snapshot+hdfs進行數據備份
0、es集群數據備份的必要性
任何一個存儲數據的軟件,都需要定期的備份我們的數據。es replica提供了運行時的高可用保障機制,可以容忍少數節點的故障和部分數據的丟失,但是整體上卻不會丟失任何數據,而且不會影響集群運行。
但是replica沒法進行災難性的數據保護,比如說機房徹底停電,所有機器全部宕機等等情況。對于這種災難性的故障,我們就需要對集群中的數據進行備份了,集群中數據的完整備份。
1、ES數據備份儲存如何選擇?
要備份集群數據,就要使用snapshot api。這個api會將集群當前的狀態和數據全部存儲到一個外部的共享目錄中去,比如NAS,或者hdfs。
而且備份過程是非常智能的,第一次會備份全量的數據,但是接下來的snapshot就是備份兩次snapshot之間的增量數據了。數據是增量進入es集群或者從es中刪除的,那么每次做snapshot備份的時候,也會自動在snapshot備份中增量增加數據或者刪除部分數據。因此這就意味著每次增量備份的速度都是非常快的。
如果要使用這個功能,我們需要有一個預先準備好的獨立于es之外的共享目錄,用來保存我們的snapshot備份數據。es支持多種不同的目錄類型:shared filesystem,比如NAS;Amazon S3;hdfs;Azure Cloud。不過對于國內的情況而言,其實NAS應該很少用,一般來說,就用hdfs會比較多一些,跟hadoop這種離線大數據技術棧整合起來使用。
2、創建備份倉庫
方式一 利用fs(共享文件系統)創建和查詢倉
PUT _snapshot/my_backup {"type": "fs", "settings": {"location": "/mount/backups/my_backup" } }這里用了shared filesystem作為倉庫類型,包括了倉庫名稱以及倉庫類型是fs,還有倉庫的地址。這個里面就包含了倉庫的一些必要的元數據了。可能還有其他的一些參數可以配置,主要是基于我們的node和網絡的性能來配置。
- max_snapshot_bytes_per_sec,這個參數用于指定數據從es灌入倉庫的時候,進行限流,默認是20mb/s。
- max_restore_bytes_per_sec,這個參數用于指定數據從倉庫中恢復到es的時候,進行限流,默認也是20mb/s。
假如說網絡是非常快速的,那么可以提高這兩個參數的值,可以加快每次備份和恢復的速度,比如下面:
POST _snapshot/my_backup/ {"type": "fs","settings": {"location": "/mount/backups/my_backup","max_snapshot_bytes_per_sec" : "50mb", "max_restore_bytes_per_sec" : "50mb"} }創建一個倉庫之后,就可以查看這個倉庫的信息了:GET /_snapshot/my_backup,或者是查看所有的倉庫,GET /_snapshot/_all。
可能返回如下的信息:
{"my_backup": {"type": "fs","settings": {"compress": true,"location": "/mount/backups/my_backup"}} }方式二:基于hdfs創建倉庫(推薦)
但是其實如果在國內使用es的話,還是建議跟hadoop生態整合使用,不要用那種shared filesystem。
可以用hadoop生態的hdfs分布式文件存儲系統。
(1)安裝repository-hdfs的插件
首先先要安裝repository-hdfs的插件:bin/elasticsearch-plugin install repository-hdfs,必須在每個節點上都安裝,然后重啟整個集群。
kill -SIGTERM 15516 (自己的PID)su elasticsearch elasticsearch -d -Epath.conf=/etc/elasticsearch (-E 指定配置文件路徑)curl -XGET elasticsearch02:9200/_cat/nodes?v在3個hdfs node上,都加入hdfs-site.xml,禁止權限檢查,如果要修改這個配置文件,要先在/usr/local/hadoop/sbin,運行./stop-dfs.sh,停止整個hdfs集群,然后在3個node上,都修改hdfs-site.xml,加入下面的配置,禁止權限的檢查
<property><name>dfs.permissions</name><value>false</value> </property>hdfs snapshot/restore plugin是跟最新的hadoop 2.x整合起來使用的,這里選hadoop 2.7.1。
所以如果我們使用的hadoop版本跟這個es hdfs plugin的版本不兼容,那么考慮在hdfs plugin的文件夾里,將hadoop相關jar包都替換成我們自己的hadoop版本對應的jar包。即使hadoop已經在es所在機器上也安裝了,但是為了安全考慮,還是應該將hadoop jar包放在hdfs plugin的目錄中。
(2)創建hdfs倉庫
安裝好了hdfs plugin之后,就可以創建hdfs倉庫了,用如下的命令即可:
curl -XGET 'http://localhost:9200/_count?pretty' -d ' {"query": {"match_all": {}} } 'elasticsearch02 成master了,所以命令切成了 elasticsearch02主機上
curl -XPUT 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository2' -d ' {"type": "hdfs","settings": {"uri": "hdfs://elasticsearch02:9000/","path": "elasticsearch/respositories/my_hdfs_repository","conf.dfs.client.read.shortcircuit": "false","max_snapshot_bytes_per_sec" : "50mb", "max_restore_bytes_per_sec" : "50mb"} }'(3)驗證倉庫
如果一個倉庫被創建好之后,我們可以立即去驗證一下這個倉庫是否可以在所有節點上正常使用。
verify參數都可以用來做這個事情,比如下面的命令。這個命令會返回一個node列表,證明那些node都驗證過了這個倉庫是ok的,可以使用的
curl -XPOST 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/_verify'出問題的話,使用下面的方式來修復下
先停止整個es集群,然后在3個節點上,都加入下面的配置,然后用elasticsearch賬號重啟整個es集群
/usr/local/elasticsearch/plugins/repository-hdfs/plugin-security.policypermission java.lang.RuntimePermission "accessDeclaredMembers";permission java.lang.RuntimePermission "getClassLoader";permission java.lang.RuntimePermission "shutdownHooks";permission java.lang.reflect.ReflectPermission "suppressAccessChecks";permission javax.security.auth.AuthPermission "doAs";permission javax.security.auth.AuthPermission "getSubject";permission javax.security.auth.AuthPermission "modifyPrivateCredentials";permission java.security.AllPermission;permission java.util.PropertyPermission "*", "read,write";permission javax.security.auth.PrivateCredentialPermission "org.apache.hadoop.security.Credentials * \"*\"", "read"; /usr/local/elasticsearch/config/jvm.options -Djava.security.policy=file:////usr/local/elasticsearch/plugins/repository-hdfs/plugin-security.policy3、對索引進行snapshotting備份
(1)對所有open的索引進行snapshotting備份
一個倉庫可以包含多份snapshot,每個snapshot是一部分索引的備份數據,創建一份snapshot備份時,我們要指定要備份的索引。
比如下面這行命令:PUT _snapshot/my_hdfs_repository/snapshot_1,這行命令就會將所有open的索引都放入一個叫做snapshot_1的備份,并且放入my_backup倉庫中。
這個命令會立即返回,然后備份操作會被后臺繼續進行。
如果我們不希望備份操作以后臺方式運行,而是希望在前臺發送請求時等待備份操作執行完成,那么可以加一個參數即可,比如下面這樣:PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true。
curl -XPUT 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1'(2)對指定的索引進行snapshotting備份
默認的備份是會備份所有的索引.
但是有的時候,可能我們不希望備份所有的索引,有些可能是不重要的數據,而且量很大,沒有必要占用我們的hdfs磁盤資源,那么可以指定備份少數重要的數據即可。此時可以使用下面的命令去備份指定的索引:
PUT _snapshot/my_backup/snapshot_2 {"indices": "index_1,index_2","ignore_unavailable": true,"include_global_state": false,"partial": true }ignore_unavailable如果設置為true的話,那么那些不存在的index就會被忽略掉,不會進行備份過程中。
默認情況下,這個參數是不設置的,那么此時如果某個index丟失了,會導致備份過程失敗。
設置include_global_state為false,可以阻止cluster的全局state也作為snapshot的一部分被備份。
默認情況下,如果某個索引的部分primary shard不可用,那么會導致備份過程失敗,那么此時可以將partial設置為true。
而且snapshotting的過程是增量進行的,每次執行snapshotting的時候,es會分析已經存在于倉庫中的snapshot對應的index file,然后僅僅備份那些自從上次snapshot之后新創建的或者有過修改的index files。這就允許多個snapshot在倉庫中可以用一種緊湊的模式來存儲。
而且snapshotting過程是不會阻塞所有的es讀寫操作的,然而,在snapshotting開始之后,寫入index中的數據,是不會反應到這次snapshot中的。每次snapshot除了創建一份index的副本之外,還可以保存全局的cluster元數據,里面包含了全局的cluster設置和template。
每次只能執行一次snapshot操作,如果某個shard正在被snapshot備份,那么這個shard此時就不能被移動到其他node上去,這會影響shard rebalance的操作。只有在snapshot結束之后,這個shard才能夠被移動到其他的node上去。
4、查看snapshot備份列表
一旦我們在倉庫中備份了一些snapshot之后,就可以查看這些snapshot相關的詳細信息了,使用這行命令就可以查看指定的snapshot的詳細信息:GET _snapshot/my_backup/snapshot_2,結果大致如下所示。
當然也可以查看所有的snapshot列表,GET _snapshot/my_backup/_all。
curl -XGET 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1?pretty'{"snapshots" : [{"snapshot" : "snapshot_1","uuid" : "x8DXcrp2S0md-BC9ftYZqw","version_id" : 5050099,"version" : "5.5.0","indices" : ["my_index"],"state" : "SUCCESS","start_time" : "2017-07-08T19:54:54.914Z","start_time_in_millis" : 1499543694914,"end_time" : "2017-07-08T19:54:56.886Z","end_time_in_millis" : 1499543696886,"duration_in_millis" : 1972,"failures" : [ ],"shards" : {"total" : 5,"failed" : 0,"successful" : 5}}] }5、刪除snapshot備份
如果要刪除過于陳舊的snapshot備份快照,那么使用下面這行命令即可:DELETE _snapshot/my_backup/snapshot_2。
記住,一定要用api去刪除snapshot,不要自己手動跑到hdfs里刪除這個數據。
因為snapshot是增量的,有可能很多snapshot依賴于底層的某一個公共的舊的snapshot segment。但是delete api是理解數據如何增量存儲和互相依賴的,所以可以正確的刪除那些不用的數據。如果我們自己手工進行hdfs文件刪除,可能導致我們的backup數據破損掉,就無法使用了
curl -XDELETE 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1'6、監控snapshotting的進度
使用wait_for_completion可以在前臺等待備份完成,但是實際上也沒什么必要,因為可能要備份的數據量特別大,難道還等待1個小時??
看著是不太現實的,所以一般還是在后臺運行備份過程,然后使用另外一個監控api來查看備份的進度.
首先可以獲取一個snapshot ID:GET _snapshot/my_backup/snapshot_3。如果這個snapshot還在備份過程中,此時我們就可以看到一些信息,比如什么時候開始備份的,已經運行了多長時間,等等。然而,這個api用了跟snapshot一樣的線程池去執行,如果我們在備份非常大的shard,進度的更新可能會非常之慢。
一個更好的選擇是用_status API,GET _snapshot/my_backup/snapshot_3/_status,這個api立即返回最詳細的數據。
這里我們可以看到總共有幾個shard在備份,已經完成了幾個,還剩下幾個,包括每個索引的shard的備份進度:
curl -XGET 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1'7、取消snapshotting備份過程
如果我們想要取消一個正在執行的snapshotting備份過程,比如我們發現備份時間過于長,希望先取消然后在晚上再運行,或者是因為不小心誤操作發起了一次備份操作,這個時候就可以運行下面這條命令:DELETE _snapshot/my_backup/snapshot_3。也就是立即刪除這個snapshot,這個命令會去取消snapshot的過程,同時將備份了一半的倉庫中的數據給刪除掉。
curl -XDELETE 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1'基于snapshot+hdfs+restore進行數據恢復
1、基于snapshot的數據恢復
正經備份,一般來說,是在一個shell腳本里,你用crontab做一個定時,比如每天凌晨1點,就將所有的數據做一次增量備份,當然,如果你的數據量較大,每小時做一次也ok。
shell腳本里,就用curl命令,自動發送一個snapshot全量數據的請求。那么這樣的話,就會自動不斷的去做增量備份。
20190721,做了一次snapshot,snapshot_20190721
20190722,又做了一次snapshot,snapshot_20190722
這兩次snapshot是有關聯關系的,因為第二次snapshot是基于第一次snapshot的數據去做的增量備份
如果你要做數據恢復,比如說,你自己誤刪除,不小心將整個index給刪除掉了,數據丟了,很簡單,直接用最新的那個snapshot就可以了,比如snapshot_20170722
如果,你是做了一些錯誤的數據操作,舉個例子,今天你的程序有個bug,寫入es中的數據都是錯誤的,需要清洗數據,重新導入
這個時候,雖然最新的snapshot_20190722,但是也可以手動選擇snapshot_20190721 snapshot,去做恢復,相當于是將數據恢復到20170721號的數據情況,忽略掉20190722號的數據的變更
然后重新去導入數據
如果我們用一些腳本定期備份數據之后,那么在es集群故障,導致數據丟失的時候,就可以用_restore api進行數據恢復了。比如下面這行命令:POST _snapshot/my_hdfs_repository/snapshot_1/_restore。這個時候,會將那個snapshot中的所有數據恢復到es中來,如果snapshot_1中包含了5個索引,那么這5個索引都會恢復到集群中來。不過我們也可以選擇要從snapshot中恢復哪幾個索引。
我們還可以通過一些option來重命名索引,恢復索引的時候將其重命名為其他的名稱。在某些場景下,比如我們想恢復一些數據但是不要覆蓋現有數據,然后看一下具體情況,用下面的命令即可恢復數據,并且進行重命名操作:
POST /_snapshot/my_hdfs_repository/snapshot_1/_restore {"indices": "index_1", "ignore_unavailable": true,"include_global_state": true,"rename_pattern": "index_(.+)", "rename_replacement": "restored_index_$1" }index_01
restores_index_01
這個restore過程也是在后臺運行的,如果要在前臺等待它運行完,那么可以加上wait_for_completion flag:
POST _snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true?wait_for_completion=true,包括之前講解的備份,也是一樣的,對運維中的自動化shell腳本,很重要,你的shell腳本里,要比如等待它備份完成了以后,才會去執行下一條命令.
restore過程只能針對已經close掉的index來執行,而且這個index的shard還必須跟snapshot中的index的shard數量是一致的。restore操作會自動在恢復好一個index之后open這個index,或者如果這些index不存在,那么就會自動創建這些index。如果通過include_global_state存儲了集群的state,還會同時恢復一些template。
默認情況下,如果某個索引在恢復的時候,沒有在snapshot中擁有所有的shard的備份,那么恢復操作就會失敗,比如某個shard恢復失敗了。但是如果將partial設置為true,那么在上述情況下,就還是可以進行恢復操作得。不過在恢復之后,會自動重新創建足夠數量的replica shard。
此外,還可以在恢復的過程中,修改index的一些設置,比如下面的命令:
POST /_snapshot/my_backup/snapshot_1/_restore {"indices": "index_1","index_settings": {"index.number_of_replicas": 0},"ignore_index_settings": ["index.refresh_interval"] }curl -XDELETE 'http://elasticsearch02:9200/my_index?pretty' curl -XGET 'http://elasticsearch02:9200/my_index/my_type/1' curl -XPOST 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1/_restore?pretty' curl -XGET 'http://elasticsearch02:9200/my_index/my_type/1'為啥總是用curl命令,特別是可能要封裝一些自動化的shell腳本,去做一些es的運維操作,比如自動定時備份 ,可能你要做一次恢復,連帶執行很多es的運維命令,可以提前封裝一個shell腳本,大量的就是要用curl命令
2、監控restore的進度
從一個倉庫中恢復數據,其實內部機制跟從其他的node上恢復一個shard是一樣的。如果要監控這個恢復的過程,可以用recovery api,比如:GET restored_index_3/_recovery。如果要看所有索引的恢復進度:GET /_recovery/。可以看到恢復進度的大致的百分比。結果大致如下所示:
curl -XGET 'http://elasticsearch02:9200/my_index/_recovery?pretty'3、取消恢復過程
如果要取消一個恢復過程,那么需要刪除已經被恢復到es中的數據。因為一個恢復過程就只是一個shard恢復,發送一個delete操作刪除那個索引即可,比如:DELETE /restored_index_3。如果那個索引正在被恢復,那么這個delete命令就會停止恢復過程,然后刪除已經恢復的 所有數據。
curl -XDELETE 'http://elasticsearch02:9200/my_index'總結
以上是生活随笔為你收集整理的白话Elasticsearch72_利用HDFS备份与恢复ES生产集群的数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Elasticsearch-Jest 配
- 下一篇: 白话Elasticsearch73_ES