Elasticsearch snapshot 備份的使用方法
常見的資料庫都會提供備份的機制,以解決在資料庫無法使用的情況下,可以開啟新的例項,然後通過備份來恢復資料減少損失。雖然 Elasticsearch 有良好的容災性,但由於以下原因,其依然需要備份機制。
1、資料災備。在整個叢集無法正常工作時,可以及時從備份中恢復資料。 2、歸檔資料。隨著資料的積累,比如日誌類的資料,叢集的儲存壓力會越來越大,不管是記憶體還是磁碟都要承擔資料增多帶來的壓力,此時我們往往會選擇只保留最近一段時間的資料,比如1個月,而將1個月之前的資料刪除。如果你不想刪除這些資料,以備後續有檢視的需求,那麼你就可以將這些資料以備份的形式歸檔。 3、遷移資料。當你需要將資料從一個叢集遷移到另一個叢集時,也可以用備份的方式來實現。 Elasticsearch 做備份有兩種方式,一是將資料匯出成文字檔案,比如通過 elasticdump、esm 等工具將儲存在 Elasticsearch 中的資料匯出到檔案中。二是以備份 elasticsearch data 目錄中檔案的形式來做快照,也就是 Elasticsearch 中 snapshot 介面實現的功能。第一種方式相對簡單,在資料量小的時候比較實用,當應對大資料量場景效率就大打折扣。我們今天就著重講解下第二種備份的方式,即 snapshot api 的使用。
備份要解決備份到哪裡、如何備份、何時備份和如何恢復的問題,那麼我們接下來一個個解決。
- 備份到哪裡
在 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 中來備份資料了。
- 如何備份
有了 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 . 命令看一下該目錄的大小,方便後續做對比。
- 何時備份
通過上面的步驟我們成功建立了一個備份,但隨著資料的新增,我們需要對新增的資料也做備份,那麼我們如何做呢?方法很簡單,只要再建立一個快照 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、磁碟和網路資源,但還是建議大家儘量在閒時做備份。
- 如何恢復
所謂“養兵千日,用兵一時”,我們該演練下備份的成果,將其恢復出來。通過呼叫如下 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 做恢復。我們這裡就不做說明了。
- 其他
由於 Elasticsearch 版本更新比較快,因此大家在做備份與恢復的時候,要注意版本問題,同一個大版本之間的備份與恢復是沒有問題的,比如都是 5.1 和 5.6 之間可以互相備份恢復。但你不能把一個高版本的備份在低版本恢復,比如將 6.x 的備份在 5.x 中恢復。而低版本備份在高版本恢復有一定要求:
-
5.x 可以在 6.x 恢復
-
2.x 可以在 5.x 恢復
-
1.x 可以在 2.x 恢復
其他跨大版本的升級都是不可用的,比如1.x 的無法在 5.x 恢復。這裡主要原因還是 Lucene 版本問題導致的,每一次 ES 的大版本升級都會伴隨 Lucene 的大版本,而 Lucene 的版本是儘量保證向前相容,即新版可以讀舊版的檔案,但版本跨越太多,無法實現相容的情況也在所難免了。
- 繼續學習