ElasticSearch 快照備份和還原


ES提供快照和恢復功能,我們可以在遠程文件系統倉庫(比如共享文件系統、S3、HDFS等)中單獨給部分索引或者整個集羣創建快照。這些快照對備份非常有用,它們能相對較快地被恢復。但是,快照只能被恢復到可以讀取他們的ES版本中:

  • 在5.x創建的索引的快照可以被恢復到6.x;
  • 在2.x創建的索引的快照可以被恢復到5.x;
  • 在1.x創建的索引的快照可以被恢復到2.x;

相反,在1.x中創建的索引快照不能被恢復到5.x或者6.x,在2.x中創建的索引快照不能被恢復到6.x中。

快照是增量的,可以包含在多個ES版本中創建的索引。如果在一個快照中的任何索引時在不兼容的ES版本中創建的,你將不能恢復該快照。

在升級前備份數據的時候,如果快照中的索引是在與你升級版本不兼容的ES版本中創建的,那麼這些快照將不能被恢復。

如果你的情況是需要恢復一個與你當前運行的集羣版本不兼容的索引快照,你可以先恢復到最新的兼容版本中,然後在當前版本中使用 reindex-from-remote 重建索引。遠程Reindexing只能在源索引source爲enabled的情況下進行。獲取並重建數據索引的時間可能比簡單恢復快照要長的多。如果你的數據量較大,建議先用一部分數據測試遠程reindex,以便了解需要花費的時間。

Repositories

必須先註冊一個快照倉庫,然後才能進行快照和恢復操作。建議爲每個主版本創建一個新快照倉庫。有效的倉庫設置取決於倉庫類型。

如果多個集羣註冊同一個快照倉庫,只有一個集羣可以對倉庫進行寫訪問,其他所有集羣應該設置該倉庫爲 readonly 模式。

跨主版本時快照格式可能會改變,所以不同版本的集羣寫同一個快照倉庫,某個版本寫的快照可能對其他版本不可見,倉庫快照也存在問題。ES不支持倉庫對所有集羣設置爲readonly,其中一個集羣和不同主版本的多個集羣一起工作。

1. 註冊創建快照倉庫

curl -X PUT "localhost:9200/_snapshot/my_backup" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "my_backup_location"
  }
}
'

2. 查看已註冊快照倉庫

curl -X GET "localhost:9200/_snapshot/my_backup"

可以使用逗號間隔多個倉庫,星號通配符匹配倉庫名字,下面示例返回倉庫名以repo開頭的和包含backup的倉庫信息

curl -X GET "localhost:9200/_snapshot/repo*,*backup*"

獲取所有已註冊快照倉庫,省略倉庫名或者使用_all

curl -X GET "localhost:9200/_snapshot"

或者

curl -X GET "localhost:9200/_snapshot/_all"

3. 查看快照倉庫列表

# curl -X GET "10.17.4.200:9200/_cat/repositories?v"
id                   type
elasticsearch_backup   fs
test                   fs

4. Shared File System Repository

共享文件系統倉庫(“type”: “fs”)使用共享文件系統存快照,如果要註冊共享文件系統倉庫,必須在所有master和data節點掛載相同的共享文件系統到同一個路徑位置。這個路徑位置(或者它的一個父目錄)必須在所有master和data節點的path.repo設置上註冊。

假設共享文件系統掛載到 /mount/backups/my_fs_backup_location,應該在elasticsearch.yml文件中添加如下配置:

path.repo: ["/mount/backups", "/mount/longterm_backups"]

The path.repo setting supports Microsoft Windows UNC paths as long as at least server name and share are specified as a prefix and back slashes are properly escaped:

path.repo: ["\\\\MY_SERVER\\Snapshots"]

所有節點啓動之後,執行下面的命令註冊名字爲my_fs_backup的共享文件系統倉庫:

curl -X PUT "localhost:9200/_snapshot/my_fs_backup" -H 'Content-Type: application/json' -d'
{
    "type": "fs",
    "settings": {
        "location": "/mount/backups/my_fs_backup_location",
        "compress": true
    }
}
'

如果倉庫路徑使用相對路徑,該路徑將根據在path.repo中定義的第一個路徑決定:

curl -X PUT "localhost:9200/_snapshot/my_fs_backup" -H 'Content-Type: application/json' -d'
{
    "type": "fs",
    "settings": {
        "location": "my_fs_backup_location",
        "compress": true
    }
}
'

compress: Turns on compression of the snapshot files. Compression is applied only to metadata files (index mapping and settings). Data files are not compressed. Defaults to true.

5. 倉庫確認

倉庫被註冊之後,會立即在所有master和data節點上被驗證以確保對當前集羣所有的節點有效。在註冊或者更新倉庫時,參數verify可以顯示禁用倉庫覈實確認操作:

curl -X PUT "localhost:9200/_snapshot/my_unverified_backup?verify=false" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "my_unverified_backup_location"
  }
}
'

驗證過程可以通過下面的命令手動執行:

curl -X POST "localhost:9200/_snapshot/my_unverified_backup/_verify"

上面返回一個倉庫驗證成功的節點列表或者驗證失敗時的錯誤信息。

Snapshot

創建快照

一個倉庫可以擁有同一個集羣的多個快照。在一個集羣中快照擁有一個唯一名字作爲標識。在倉庫 my_backup 中創建名字爲 snapshot_1 的快照,可以通過執行下面的命令來實現:

curl -X PUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"

參數 wait_for_completion 決定請求是在快照初始化後立即返回(默認),還是等快照創建完成之後再返回。快照初始化時,所有之前的快照信息會被加載到內存,所以在一個大的倉庫中改請求需要若干秒(甚至分鐘)才能返回,即使參數 wait_for_completion 的值設置爲 false。

默認情況下,創建一個快照會包含集羣中所有打開和啓動狀態的索引。可以通過在創建快照的請求體中定義索引列表來改變這個默認處理:

curl -X PUT "localhost:9200/_snapshot/my_backup/snapshot_2?wait_for_completion=true" -H 'Content-Type: application/json' -d'
{
  "indices": "index_1,index_2",
  "ignore_unavailable": true,
  "include_global_state": false
}
'

要包含到快照中索引列表可以使用支持多個索引語法的 indices 參數來指定。快照請求也支持 ignore_unavailable 選項,該選項設置爲 true 時,在創建快照時會忽略不存在的索引。默認情況下,如果選項 ignore_unavailable 沒有設值,一個索引缺失,快照請求會失敗。
通過設置 include_global_state 爲 false,可以阻止集羣全局狀態信息被保存爲快照的一部分。默認情況下,如果如果一個快照中的一個或者多個索引沒有所有主分片可用,整個快照創建會失敗,該情況可以通過設置 partial 爲 true 來改變。

快照名可以通過使用 date_math_expressions 來自動獲得,和創建新索引時類似。注意特殊字符需要 URI 轉碼處理。

例如,在名字中使用當前日期,比如 snapshot-2018.05.11,來創建快照,可以使用如下命令完成:

# PUT /_snapshot/my_backup/<snapshot-{now/d}>
curl -X PUT "localhost:9200/_snapshot/my_backup/%3Csnapshot-%7Bnow%2Fd%7D%3E"

索引的快照過程是增量的。在創建索引快照的過程中,ElasticSearch會分析倉庫中已經存在的索引文件,只拷貝那些在最後一次快照之後被創建或者更新的文件。That allows multiple snapshots to be preserved in the repository in a compact form. 快照過程以非阻塞的方式執行,所有的索引和搜索操作都可以對正在被創建快照的索引繼續執行。一個快照表示的是這個索引在快照被創建時間點的索引視圖,所以在索引過程開始之後被添加到索引中的記錄不會出現在快照中。快照過程會立即在已經啓動的主分片上開始並且不會在此時重新定位。在版本 1.2.0 以前,如果共同快照中的索引在集羣中發生任何重新定位或者初始化(the cluster has any relocating or initializing primaries of indices participating in the snapshot),快照操作將失敗,從 1.2.0 版本開始,ElasticSearch 會等重新定位或者初始化主分片完成之後再進行快照操作。

除了創建每個索引的備份,快照過程也能存儲全局集羣元數據,包括持久化的集羣設置和模版。臨時設置和註冊的快照倉庫不會存儲爲快照的一部分。

任何時候,在集羣中只能有一個快照過程被執行。當創建一個特定分片的快照時,該分片不能移動到另一個節點,這會干擾(interfere with)平衡進程和分配過濾(allocation filtering)。ElasticSearch 一旦在快照完成之後才能移動分片到其他節點。

查看快照

一旦快照創建完成,可以通過以下命令獲取快照信息:

curl -X GET "localhost:9200/_snapshot/my_backup/snapshot_1"

這個命令返回快照的基本信息,包括開始合結束時間、創建快照的 ElasticSearch 版本、包含的索引列表、快照當前狀態和快照期間產生的失敗索引列表。快照的狀態有:

狀態 描述
IN_PROGRESS The snapshot is currently running.
SUCCESS The snapshot finished and all shards were stored successfully.
FAILED The snapshot finished with an error and failed to store any data.
PARTIAL The global cluster state was stored, but data of at least one shard wasn’t stored successfully. The failure section in this case should contain more detailed information about shards that were not processed correctly.
INCOMPATIBLE The snapshot was created with an old version of Elasticsearch and therefore is incompatible with the current version of the cluster.

跟倉庫類似,在一次查詢中可以查詢多個快照的信息,也支持通配符:

curl -X GET "localhost:9200/_snapshot/my_backup/snapshot_*,some_other_snapshot"

倉庫當前存儲的所有快照可以通過下面的命令獲取:

curl -X GET "localhost:9200/_snapshot/my_backup/_all"

如果一些快照不可用,會導致獲取命令執行失敗。可以通過設置布爾參數 ignore_unavailable 來指定返回當前可用的所有快照。

從基於雲存儲的倉庫中獲取所有的快照,在消耗和性能方面看代價都比較高。如果只是獲取快照的 names/uuids 和每個快照的索引列表,可以設置可選的布爾參數 verbose 爲 true,這樣再執行快照的獲取,性能表現更好,消耗更划算。注意,設置 verbose 爲 false,會忽略關於快照的所有其他信息,例如狀態信息、快照分片的數量等,verbose 參數的默認值爲 true。

當前正在運行的快照可以使用如下命令獲取:

curl -X GET "localhost:9200/_snapshot/my_backup/_current"

刪除快照

從倉庫中刪除一個快照,使用如下命令:

curl -X DELETE "localhost:9200/_snapshot/my_backup/snapshot_2"

當一個快照從倉庫中刪除,ElasticSearch 將刪除該快照關聯的但不被其他快照使用的所有文件。如果在快照創建的時候執行快照刪除操作,此快照創建進程將終止且所有該進程已創建的文件也將被清理。所以,快照刪除操作可以用來取消錯誤啓動的長時間運行的快照操作。

刪除倉庫

可以使用下面命令註銷倉庫:

curl -X DELETE "localhost:9200/_snapshot/my_backup"

當一個倉庫被註銷時,ElasticSearch 只刪除倉庫存儲快照的引用位置,快照本身沒有被刪除並且在原來的位置。

Restore

快照可以通過執行以下命令恢復

curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore"

默認情況下,快照中的所有索引將被恢復,集羣狀態不被恢復。可以通過在恢復請求中使用 indices 和 include_global_state 選項來指定要恢復的索引和允許恢復集羣全局狀態。索引列表支持多索引語法。rename_pattern 和 rename_replacement 選項在恢復時通過正則表達式來重命名索引。設置 include_aliases 爲 false 可以防止與索引關聯的別名被一起恢復。

curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore" -H 'Content-Type: application/json' -d'
{
  "indices": "index_1,index_2",
  "ignore_unavailable": true,
  "include_global_state": true,
  "rename_pattern": "index_(.+)",
  "rename_replacement": "restored_index_$1"
}
'

恢復操作可以在正常運行的集羣上執行。已存在的索引只能在關閉狀態下才能恢復,並且要跟快照中索引擁有相同數目的分片。還原操作自動打開關閉狀態的索引,如果被還原索引在集羣不存在,將創建新索引。如果集羣狀態通過 include_global_state (默認是 false)選項被還原,在集羣中不存在的模板會被新增,已存在的同名模板會被快照中的模板替換。持久化設置會被添加到現有的持久化設置中。

部分還原

默認情況下,如果參與恢復操作的一個或者多個索引沒有全部可用分片的快照,整個恢復操作將會失敗。比如部分分片快照備份操作失敗,上面的情況就會發生。這種情況依然可以通過設置 partial 爲 true 來實現快照的恢復。注意在這種情況下,只有成功完成快照備份的分片纔會被還原,而所有丟失的 其它分片將被創建成空分片。

恢復過程中修改索引設置

在恢復過程中,大部分的索引配置會被覆蓋。例如,下面的命令將恢復索引 index_1,不創建任何副本並切換回默認的索引刷新時間間隔:

curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore" -H 'Content-Type: application/json' -d'
{
  "indices": "index_1",
  "index_settings": {
    "index.number_of_replicas": 0
  },
  "ignore_index_settings": [
    "index.refresh_interval"
  ]
}
'

請注意,有些設置不能再恢復操作時被修改,比如 index.number_of_shards。

恢復到不同的集羣

存儲在快照中的信息是不和特定的集羣或者集羣名綁定的。因此可以將一個集羣的快照恢復到另外一個集羣中去。需要做的就是在新的集羣中註冊包含快照的倉庫,然後啓動恢復快照過程。新的集羣不必具有相同的大小和拓撲結構(topology)。但是,新集羣的版本必須和創建快照的集羣的版本一致或者更高(只能高出1個主版本)。例如,可以恢復1.x版本的快照到2.x版本的集羣中,但是不能恢復到5.x版本的集羣中。

如果新集羣大小比原集羣小,需要做一些額外的考慮。首先,確保新集羣具有足夠的容量來存儲快照中的所有索引。恢復過程中可以通過修改索引配置來降低副本數量,這樣有助於恢復快照到更小的集羣。也可以使用 indices 參數來指定恢復索引的子集。

如果原來集羣中的索引使用了分片分配過濾器(shard allocation filtering)來分配索引到特定的節點,那麼相同的規則將在新集羣中被執行。所以,如果新集羣不包含具有可以使被還原索引分配到自身的的屬性的節點,索引將不會被成功恢復,除非在恢復時更改索引的分配配置。

恢復操作還會檢查恢復持久化設置是否與當前集羣兼容,以避免意外恢復不兼容的設置,例如 discovery.zen.minimum_master_nodes,因此在添加所必需數目的備選主節點之前,禁用較小的集羣。如果需要恢復具有不兼容持久化設置的快照,則請嘗試在沒有全局集羣狀態的情況下執行。

快照狀態

使用以下命令可以獲取當前運行快照列表的詳細狀態信息:

curl -X GET "localhost:9200/_snapshot/_status"

可以指定快照名,以獲取指定快照的信息,即使它不是正在運行狀態:

curl -X GET "localhost:9200/_snapshot/my_backup/snapshot_1/_status"

也支持多個ID:

curl -X GET "localhost:9200/_snapshot/my_backup/snapshot_1,snapshot_2/_status"

Monitoring snapshot/restore progress

有幾種方法可以用來監測快照創建與還原正在運行時的執行進度。在創建快照與還原時指定 wait_for_completion 參數來阻塞客戶端,直到操作完成,這是一個可以用來獲取操作完成通知的最簡單方法。

快照操作還可以通過定期獲取快照信息來監測:

curl -X GET "localhost:9200/_snapshot/my_backup/snapshot_1"

請注意,獲取快照信息操作與創建快照操作使用相同的資源和線程池,因此在執行獲取快照信息時如果創建快照的線程正在備份大的分片,可能導致要在返回結果前等待可用的資源。在非常大的分片備份情況中等待的時間回很長。

爲了獲得更多的直接和完整的信息,可以用快照的status命令來查看:

curl -X GET "localhost:9200/_snapshot/my_backup/snapshot_1/_status"

快照信息命令返回正在進行的快照的基本信息,而快照狀態命令返回參與快照的每個分片的當前狀態完整分解(complete breakdown of the current state for each shard participating in the snapshot)。

還原過程是基於 Elasticsearch 標準恢復機制。因此標準的恢復監控服務可以用來監控還原的狀態。當集羣執行還原操作時通常會進入 red 狀態。這是因爲還原操作是從恢復被還原索引的主分片開始的,在此期間主分片狀態變爲不可用,表現爲集羣狀態爲 red。一旦主分片恢復完成,ElasticSearch 開始創建所需數目的副本的標準複製過程,這時集羣切換到 yellow 狀態。一旦完成所有必需副本的創建,集羣變切換到 green 狀態。

集羣健康狀態只提供了還原過程的一個比較粗略的一個狀態。還可以通過使用 indices recovery 和 cat recovery 接口獲取更詳細的恢復過程的狀態信息。

Stopping currently running snapshot and restore operations

快照和恢復框架只允許在同一個時間點運行一個快照或者一個恢復操作。如果當前運行的快照被錯誤執行,或者執行時間特別長,可以通過快照刪除操作來終止操作。快照刪除操作會檢查要刪除的快照是否正在運行,如果是,刪除操作會在從倉庫中刪除快照數據之前停止快照運行。

curl -X DELETE "localhost:9200/_snapshot/my_backup/snapshot_1"

恢復操作使用標準分片恢復機制。所以任何當前正在運行的恢復操作都可以通過刪除正在被恢復的索引來取消。請注意,所有已刪除索引的數據都將因爲這個操作被移除。

Effect of cluster blocks on snapshot and restore operations

許多快照備份和恢復操作都會被集羣和索引的鎖影響。例如,註冊和註銷倉庫需要寫全局元數據。快照操作需要要求所有的索引及其元數據以及全局元數據可讀。恢復操作要求全局元數據可寫,而索引級別的鎖在恢復過程中被忽略,因爲索引的恢復本質上是重新創建索引。請注意,倉庫內容不是集羣的一部分,因此集羣鎖不影響倉庫內部操作,比如獲取一個已註冊的倉庫的快照列表或者刪除其中的快照。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章