elasticsearch備份和還原(基於hdfs)

一寸HUI發表於2020-09-21

備份和還原,為什麼elasticsearch還需要備份呢,明明可以設定副本做到高可用,那怕啥呢?

其實在實際的生產環境中,一般最終的結果資料都是要備份的,這樣的做的目的,就是能夠以最快的速度還原資料,找回資料。明明mysql可以有主從,es有副本,備份幹啥呢?不就是為了萬無一失嗎,生產環境有時候壓力會很大,像mysql頻繁的插入和刪除資料也會導致binlog日誌同步延遲,有時候就不一定能夠做到同步,還有就是誤操作刪除了一些有用的資料呢,對吧,這個叫做有備無患。es也同樣,萬一一波操作猛如虎,一把把某個索引刪除了呢,沒有備份,到時候怎麼死的都不知道呢,所以呢,從叢集的角度去思考,許可權,資料備份,高可用,節點擴充等都很重要。elasticsearch備份資料有很多選擇,本地呀,Amazon S3, HDFS, Microsoft Azure, Google Cloud Storage這些都可以,但是我這裡選擇了hdfs,因為做大資料的熟悉呀,還有就是hdfs就是一個分散式的儲存系統,也是資料高可用的呀,只要叢集不椡,我資料依然完整,所以一點都不方了,所以這篇文章是基於HDFS的Elasticsearch的資料備份和還原。

一、瞭解下

如何儲存:可以儲存在本地,或者遠端的儲存庫:Amazon S3, HDFS, Microsoft Azure, Google Cloud Storage等

操作步驟:第一步:需要註冊快照儲存庫,第二步:才能進行建立快照

快照原則:快照屬於增量快照,每個快照只儲存上一個快照沒有的資料,但是都可以通過制定引數進行制定索引進行快照備份

恢復原則:預設恢復全部, 也可以根據需求指定恢復自己需要的索引或者資料流,可以指定索引就行單獨還原

注意點:可以使用快照的生命週期來自動的建立和管理快照,備份的時候不能直接通過複製資料進行備份,因為複製的過程中es可能會改變資料的內容,會導致資料不一致的問題

具體的備份和還原細節就交給下文了,看下版本是否支援,如果不支援通過備份還原遷移資料的,可以使用_reindex做跨叢集的資料遷移:elasticsearch跨叢集資料遷移

 

 

二、hdfs外掛安裝

本地安裝hdfs的外掛(每一個es節點都需要安裝):

下載:https://artifacts.elastic.co/downloads/elasticsearch-plugins/repository-hdfs/repository-hdfs-7.8.1.zip

安裝文件:https://www.elastic.co/guide/en/elasticsearch/plugins/7.9/plugin-management-custom-url.html  #7.9的文件不影響哈

 具體執行:./bin/elasticsearch-plugin install file:///data/hd07/car/repository-hdfs-7.8.1.zip   #這裡不要忘記加file:///

然後需要重啟ES的叢集

 cd elasticsearch-7.8.1/plugins && ll

 一看,沒毛病,一個hdfs外掛就這麼裝好了,接下來我們在hdfs上建立用來儲存elasticsearch備份的檔案目錄(注:這裡我們的hadoop是3.x的,chh6.3.2的,雖然官方說是hadoop2.7(2.x),好像也沒什麼影響)

hadoop fs -mkdir /es_bak
hadoop fs -chmod 777 /es_bak   #這裡我就簡單了,免得其他使用者沒許可權寫

這裡我們就完成了hdfs的設定了,接下來就是elasticsearch的備份和還原操作了

三、備份和還原

3.1、備份

elasticsearch的備份分為兩步,第一步:需要註冊快照儲存庫,第二步:才能進行建立快照

3.1.1、註冊快照儲存庫

快照儲存庫可以包含同一個叢集的多個快照。快照是通過叢集中的唯一名稱標識的,接下來我們就看看基於hdfs的快照儲存庫的建立:

put _snapshot/my_snapshot
{
  "type": "hdfs",
  "settings": {
    "uri": "hdfs://ip:8020/",
    "path": "/es_bak",
    "conf.dfs.client.read.shortcircuit": "true",  #其實這個引數是hdfs的一個dfs.client.read.shortcircuit,用來做節點移動計算,而不是移動資料的理念,資料本地化
    "conf.dfs.domain.socket.path": "/var/run/hdfs-sockets/dn" #配置了上面那個引數,如果hdfs叢集沒這引數dfs.domain.socket.path就會報錯
  }
}

其實CDH版本的hadoop的HDFS預設這兩個都是配置了的

 所以上面的兩個引數是可以不配置的,因為主機HDFS預設都有配置了的呢

現在我們檢視下我們建立好了的快照儲存庫:

get _snapshot/

有圖有證據,這個快照儲存庫就建立好了,接下來我們看看建立快照儲存庫的時候引數設定: 

uri #hdfs的地址hdfs://<host>:<port> #這裡需要注意一點,一般公司的hadoop都是高可用叢集,這裡要配置高可用的地址,不能寫死了
path #快照需要儲存在hdfs上的目錄/es_bak (必填)
conf.<key> #這個是用來新增hadoop的一些配置的,比如上面例子"conf.dfs.client.read.shortcircuit": "true"
load_defaults #是否載入hadoop的配置,預設載入
compress #是否壓縮後設資料,預設false
max_restore_bytes_per_sec #每個節點的恢復速率。預設為無限
max_snapshot_bytes_per_sec #每個節點快照速率。預設值為每秒40mb
readonly #設定快照儲存庫為只讀,預設false
chunk_size #覆蓋塊大小,預設disabled
security.principal #連線到安全的HDFS叢集時使用的Kerberos主體

這部分就說到這裡了,這個是官方文件:https://www.elastic.co/guide/en/elasticsearch/plugins/7.9/repository-hdfs-config.html

3.1.2、建立快照

官方網址:https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshots-take-snapshot.html

使用格式:

PUT /_snapshot/<repository>/<snapshot>
POST /_snapshot/<repository>/<snapshot>

快照建立細節:

  1. 預設情況下,快照包括群集中的所有資料流和開啟的索引,以及群集狀態。可以通過指定要備份在快照請求正文中的資料流和索引列表來更改
  2. 快照是增量的快照備份。在建立快照的過程中,Elasticsearch將分析儲存庫中已經儲存的資料流和索引檔案的列表,並僅複製自上次快照以來建立或更改的檔案。這個過程允許多個快照以緊湊的形式儲存在儲存庫中。
  3. 快照程式以非阻塞方式執行。所有索引和搜尋操作都可以繼續針對快照中的資料流或索引執行。但是,快照表示建立快照時的時間點檢視,因此在快照程式啟動後新增到資料流或索引的記錄不會包含在快照中
  4. 對於已經啟動且目前沒有重新定位的主分片,快照程式將立即啟動。Elasticsearch在快照之前等待分片的重新定位或初始化完成
  5. 除了建立每個資料流和索引的副本外,快照過程還可以儲存全域性叢集後設資料,其中包括持久的叢集設定和模板。暫態設定和註冊快照儲存庫不作為快照的一部分儲存

先來個例子:

PUT /_snapshot/my_snapshot/snapshot_1?wait_for_completion=true
{
  "indices": "index_name_word",
  "ignore_unavailable": true,
  "include_global_state": false,
  "metadata": {
    "taken_by": "lgh",
    "taken_because": "backup test"
  }
}

 

 

然後我們看看hdfs上面:

 hadoop fs -ls /es_bak

 hadoop fs -ls /es_bak/indices

 單獨的索引算是備份完成了,接下來我們看看引數:

ignore_unavailable #預設false,表示對於任何的請求丟失或關閉的資料流或索引,返回一個錯誤
indices #預設情況下,快照包括叢集中的所有資料流和索引,要來設定需要備份的索引,多個之間用逗號(,)分隔,支援正則est* or *test or te*t or *test*或者使用(-)減號排除-test3
include_global_state #快照中包含當前叢集狀態。預設值為true,主要包括這些後設資料:Persistent cluster settings,Index templates,Legacy index templates,Ingest pipelines,ILM lifecycle policies
master_timeout #指定等待連線到主節點的時間。如果在超時到期前沒有收到響應,則請求失敗並返回錯誤。預設為30秒
metadata #可新增一些備註資訊,如上個例子所示
partial #預設false,表示如果快照中包含的一個或多個索引沒有所有的主分片可用,則整個快照將失敗
wait_for_completion #預設false,請求在快照初始化時返回響應,否則要等待完成才返回

 官網還提供了根據時間字尾來建立快照名:

 

 但是實驗了一下,失敗了:

 

 不過稍微修改下就好了:

get _snapshot/my_snapshot/_all

3.2、還原

官網:https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshots-restore-snapshot.html

還原語法:POST /_snapshot/my_backup/snapshot_1/_restore

預設情況下,快照中的所有資料流和索引都將恢復,但不會恢復叢集狀態。不過可以使用indices引數指定索引進行還原恢復。

注意1:每個資料流都需要一個匹配的索引模板。使用此模板建立新的索引。如果不存在可以建立一個匹配的索引模板,或者恢復叢集的後設資料。不然的話,資料流不能滾動的建立新的索引

注意2:恢復索引時,如果索引名存在是不會被還原的,除非該索引被關閉了,還要保證分片數相同,才會進行還原,還原的過程中會自動開啟已經關閉的索引,如果索引不存在則會建立新的索引

看下具體的引數:

ignore_unavailable #預設false,表示對於任何的請求丟失或關閉的資料流或索引,返回一個錯誤
ignore_index_settings #一個逗號分隔的索引設定列表,忽略不需要恢復的索引
include_aliases #預設true,恢復時是否恢復別名
include_global_state #是否恢復叢集的狀態,後設資料資訊,預設false
index_settings #設定索引設定,可以用來覆蓋原索引的索引配置
indices ##預設情況下,快照包括叢集中的所有資料流和索引,要來設定需要還原的索引,多個之間用逗號(,)分隔,支援正則est* or *test or te*t or *test*或者使用(-)減號排除-test3
partial ##預設false,表示如果快照中包含的一個或多個索引沒有所有的主分片可用,則整個快照將失敗
rename_pattern #定義用於恢復資料流和索引的重新命名模式。與重新命名模式匹配的資料流和索引將根據rename_replacement進行重新命名。可使用正則
rename_replacement #定義重新命名替換字串
wait_for_completion #預設false,請求在快照初始化時返回響應,否則要等待完成才返回

例項一(沒有試驗,官方例項):

POST /_snapshot/my_backup/snapshot_1/_restore
{
  "indices": "data_stream_1,index_1,index_2",
  "ignore_unavailable": true,
  "include_global_state": false,              
  "rename_pattern": "index_(.+)",
  "rename_replacement": "restored_index_$1",
  "include_aliases": false
}

例項二(沒有試驗,官方例項):

POST /_snapshot/my_backup/snapshot_1/_restore
{
  "indices": "index_1",
  "ignore_unavailable": true,
  "index_settings": {  #修改索引配置
    "index.number_of_replicas": 0
  },
  "ignore_index_settings": [  #忽略的索引
    "index.refresh_interval"
  ]
}

3.3、檢視和刪除

使用_current引數檢索叢集中當前執行的所有快照

GET /_snapshot/my_backup/_current

 

 檢索關於單個快照的資訊

GET /_snapshot/my_backup/snapshot_1

 

 如上可以檢索多個快照,可以使用逗號隔開,或者使用*這樣的萬用字元以及_all表示所有,例如:

GET /_snapshot/my_backup/snapshot_*,some_other_snapshot
GET /_snapshot/_all
GET /_snapshot/my_backup,my_fs_backup
GET /_snapshot/my*
GET /_snapshot/my_backup/_all

對快照儲存庫和快照的狀態通過_status檢視:

GET /_snapshot/_status
GET /_snapshot/my_backup/_status
GET /_snapshot/my_backup/snapshot_1/_status

詳情見:https://www.elastic.co/guide/en/elasticsearch/reference/current/get-snapshot-status-api.html

刪除快照:

DELETE /_snapshot/my_backup/snapshot_1

3.4、定時備份

一種是通過crontab定時備份(這裡不說,很簡單),還有一種是通過Elasticsearch的SLM策略進行定時備份。

我們都知道備份這種事情呢不是單單去備份一次,也不能每次都去手動備份,所以es的備份提供類似crontab一樣的時間排程。可以設定快照生命週期策略來自動化快照的計時、頻率和保留。快照策略可以應用於多個資料流和索引。

使用SLM策略自動化Elasticsearch資料流和索引的日常備份。該策略獲取叢集中所有資料流和索引的快照,並將它們儲存在本地儲存庫中。它還定義了一個保留策略,並在不再需要快照時自動刪除快照。

要使用SLM,您必須配置一個快照儲存庫。儲存庫可以是本地(共享檔案系統)或遠端(雲端儲存)。遠端儲存庫可以駐留在S3、HDFS、Azure、谷歌雲端儲存或儲存庫外掛支援的任何其他平臺上

所以有兩個步驟:第一步,建立快照儲存庫,第二步:建立SLM策略

第一步:建立快照儲存庫(檢視3.1.1、註冊快照儲存庫)

第二步:建立SLM策略

官方例項:

PUT /_slm/policy/nightly-snapshots
{
  "schedule": "0 30 1 * * ?",  #配置定時排程,參考https://www.elastic.co/guide/en/elasticsearch/reference/current/trigger-schedule.html#schedule-cron
  "name": "<nightly-snap-{now/d}>",  #配置快照名字,可以通過時間為字尾名
  "repository": "my_repository",  #快照儲存庫名
  "config": {  #用於快照請求的配置,可以從建立快照中的引數配置
    "indices": ["*"]  #比如對某些索引進行快照
  },
  "retention": { #保留策略:將快照儲存30天,無論快照的年齡如何,至少保留5個且不超過50個快照
    "expire_after": "30d", 
    "min_count": 5, 
    "max_count": 50 
  }
}

實驗:

put _slm/policy/nightly-snapshots
{
  "schedule": "0 30 1 * * ?", 
  "name": "<lgh-{now{yyyy.MM.dd}}>", 
  "repository": "my_snapshot", 
  "config": { 
    "indices": ["*"] 
  },
  "retention": { 
    "expire_after": "30d", 
    "min_count": 5, 
    "max_count": 50 
  }
}

 

 

POST /_slm/policy/nightly-snapshots/_execute #手動執行快照策略

 

 

get _snapshot/my_snapshot/_all #檢視建立的快照資訊

 

 

GET /_slm/policy/nightly-snapshots?human  #檢索策略以獲取成功或失敗資訊

 

 本篇文章差不多結束了,還有要擴充的最好去官網看看,比如要進行SML安全相關的:https://www.elastic.co/guide/en/elasticsearch/reference/current/slm-and-security.html

相關文章