Elasticsearch snapshot 備份的使用方法 【備忘】


常見的數據庫都會提供備份的機制,以解決在數據庫無法使用的情況下,可以開啟新的實例,然后通過備份來恢復數據減少損失。雖然 Elasticsearch 有良好的容災性,但由於以下原因,其依然需要備份機制。

  1. 數據災備。在整個集群無法正常工作時,可以及時從備份中恢復數據。
  2. 歸檔數據。隨着數據的積累,比如日志類的數據,集群的存儲壓力會越來越大,不管是內存還是磁盤都要承擔數據增多帶來的壓力,此時我們往往會選擇只保留最近一段時間的數據,比如1個月,而將1個月之前的數據刪除。如果你不想刪除這些數據,以備后續有查看的需求,那么你就可以將這些數據以備份的形式歸檔。
  3. 遷移數據。當你需要將數據從一個集群遷移到另一個集群時,也可以用備份的方式來實現。

Elasticsearch 做備份有兩種方式,一是將數據導出成文本文件,比如通過 elasticdumpesm 等工具將存儲在 Elasticsearch 中的數據導出到文件中。二是以備份 elasticsearch data 目錄中文件的形式來做快照,也就是 Elasticsearch 中 snapshot 接口實現的功能。第一種方式相對簡單,在數據量小的時候比較實用,當應對大數據量場景效率就大打折扣。我們今天就着重講解下第二種備份的方式,即 snapshot api 的使用。

備份要解決備份到哪里、如何備份、何時備份和如何恢復的問題,那么我們接下來一個個解決。

1. 備份到哪里

在 Elasticsearch 中通過 repository 定義備份存儲類型和位置,存儲類型有共享文件系統、AWS 的 S3存儲、HDFS、微軟 Azure的存儲、Google Cloud 的存儲等,當然你也可以自己寫代碼實現國內阿里雲的存儲。我們這里以最簡單的共享文件系統為例,你也可以在本地做實驗。

首先,你要在 elasticsearch.yml 的配置文件中注明可以用作備份路徑 path.repo ,如下所示:

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

配置好后,就可以使用 snapshot api 來創建一個 repository 了,如下我們創建一個名為 my_backup 的 repository。

PUT /_snapshot/my_backup
{
  "type": "fs",
  "settings": {
    "location": "/mount/backups/my_backup"
  }
}

之后我們就可以在這個 repository 中來備份數據了。

2. 如何備份

有了 repostiroy 后,我們就可以做備份了,也叫快照,也就是記錄當下數據的狀態。如下所示我們創建一個名為 snapshot_1 的快照。

PUT /_snapshot/my_backup/snapshot_1?wait_for_completion=true

wait_for_completion 為 true 是指該 api 在備份執行完畢后再返回結果,否則默認是異步執行的,我們這里為了立刻看到效果,所以設置了該參數,線上執行時不用設置該參數,讓其在后台異步執行即可。

執行成功后會返回如下結果,用於說明備份的情況:

{
  "snapshots": [
    {
      "snapshot": "snapshot_1",
      "uuid": "52Lr4aFuQYGjMEv5ZFeFEg",
      "version_id": 6030099,
      "version": "6.3.0",
      "indices": [
        ".monitoring-kibana-6-2018.05.30",
        ".monitoring-es-6-2018.05.28",
        ".watcher-history-7-2018.05.30",
        ".monitoring-beats-6-2018.05.29",
        "metricbeat-6.2.4-2018.05.28",
        ".monitoring-alerts-6",
        "metricbeat-6.2.4-2018.05.30"
      ],
      "include_global_state": true,
      "state": "SUCCESS",
      "start_time": "2018-05-31T12:45:57.492Z",
      "start_time_in_millis": 1527770757492,
      "end_time": "2018-05-31T12:46:15.214Z",
      "end_time_in_millis": 1527770775214,
      "duration_in_millis": 17722,
      "failures": [],
      "shards": {
        "total": 28,
        "failed": 0,
        "successful": 28
      }
    }
  ]
}

返回結果的參數意義都是比較直觀的,比如 indices 指明此次備份涉及到的索引名稱,由於我們沒有指定需要備份的索引,這里備份了所有索引;state 指明狀態;duration_in_millis 指明備份任務執行時長等。

我們可以通過 GET _snapshot/my_backup/snapshot_1獲取 snapshot_1 的執行狀態。

此時如果去 /mount/backups/my_backup 查看,會發現里面多了很多文件,這些文件其實都是基於 elasticsearch data 目錄中的文件生成的壓縮存儲的備份文件。大家可以通過 du -sh . 命令看一下該目錄的大小,方便后續做對比。

3. 何時備份

通過上面的步驟我們成功創建了一個備份,但隨着數據的新增,我們需要對新增的數據也做備份,那么我們如何做呢?方法很簡單,只要再創建一個快照 snapshot_2 就可以了。

PUT /_snapshot/my_backup/snapshot_2?wait_for_completion=true

當執行完畢后,你會發現 /mount/backups/my_backup 體積變大了。這說明新數據備份進來了。要說明的一點是,當你在同一個 repository 中做多次 snapshot 時,elasticsearch 會檢查要備份的數據 segment 文件是否有變化,如果沒有變化則不處理,否則只會把發生變化的 segment file 備份下來。這其實就實現了增量備份。

elasticsearch 的資深用戶應該了解 force merge 功能,即可以強行將一個索引的 segment file 合並成指定數目,這里要注意的是如果你主動調用 force merge api,那么 snapshot 功能的增量備份功能就失效了,因為 api 調用完畢后,數據目錄中的所有 segment file 都發生變化了。

另一個就是備份時機的問題,雖然 snapshot 不會占用太多的 cpu、磁盤和網絡資源,但還是建議大家盡量在閑時做備份。

4. 如何恢復

所謂“養兵千日,用兵一時”,我們該演練下備份的成果,將其恢復出來。通過調用如下 api 即可快速實現恢復功能。

POST /_snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true
{
  "indices": "index_1",
  "rename_replacement": "restored_index_1"
}

通過上面的 api,我們可以將 index_1 索引恢復到 restored_index_1 中。這個恢復過程完全是基於文件的,因此效率會比較高。

雖然我們這里演示的是在同一個集群做備份與恢復,你也可以在另一個集群上連接該 repository 做恢復。我們這里就不做說明了。

5. 其他

由於 Elasticsearch 版本更新比較快,因此大家在做備份與恢復的時候,要注意版本問題,同一個大版本之間的備份與恢復是沒有問題的,比如都是 5.1 和 5.6 之間可以互相備份恢復。但你不能把一個高版本的備份在低版本恢復,比如將 6.x 的備份在 5.x 中恢復。而低版本備份在高版本恢復有一定要求:

1) 5.x 可以在 6.x 恢復

2) 2.x 可以在 5.x 恢復

3) 1.x 可以在 2.x 恢復

其他跨大版本的升級都是不可用的,比如1.x 的無法在 5.x 恢復。這里主要原因還是 Lucene 版本問題導致的,每一次 ES 的大版本升級都會伴隨 Lucene 的大版本,而 Lucene 的版本是盡量保證向前兼容,即新版可以讀舊版的文件,但版本跨越太多,無法實現兼容的情況也在所難免了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM