備份和還原,為什么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>
快照創建細節:
- 默認情況下,快照包括群集中的所有數據流和打開的索引,以及群集狀態。可以通過指定要備份在快照請求正文中的數據流和索引列表來更改
- 快照是增量的快照備份。在創建快照的過程中,Elasticsearch將分析存儲庫中已經存儲的數據流和索引文件的列表,並僅復制自上次快照以來創建或更改的文件。這個過程允許多個快照以緊湊的形式保存在存儲庫中。
- 快照進程以非阻塞方式執行。所有索引和搜索操作都可以繼續針對快照中的數據流或索引運行。但是,快照表示創建快照時的時間點視圖,因此在快照進程啟動后添加到數據流或索引的記錄不會包含在快照中
- 對於已經啟動且目前沒有重新定位的主分片,快照進程將立即啟動。Elasticsearch在快照之前等待分片的重新定位或初始化完成
- 除了創建每個數據流和索引的副本外,快照過程還可以存儲全局集群元數據,其中包括持久的集群設置和模板。暫態設置和注冊快照存儲庫不作為快照的一部分存儲
先來個例子:
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,請求在快照初始化時返回響應,否則要等待完成才返回
官網還提供了根據時間后綴來創建快照名:
但是實驗了一下,失敗了:
不過稍微修改下就好了:
put _snapshot/my_snapshot/<yy{now{yyyy.MM.dd}}> #參考https://www.elastic.co/guide/en/elasticsearch/reference/current/date-math-index-names.html
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