Elasticsearch提供了replica解決方案,它可以幫我們解決了如果有一個或多個node失敗了,那么我們的數據還是可以保證完整的情況,並且搜索還可以繼續進行。但是,有一種情況是我們的所有的node,或者有一部分node失敗,可能會造成我們的數據的丟失。也就是說replca不能提供一種災難性的保護機制。我們需要一種完整的備份機制。
Snapshot及Restore
在Elastic里,我們提供了一個叫做snapshot及restore API的接口。使您可以使用數據和狀態快照備份您的Elasticsearch索引和集群。 快照很重要,因為快照會在出現問題時提供您數據的副本。 如果需要回滾到舊版本的數據,則可以從存儲庫中還原快照。
如上圖所示,我們可以把當前index的狀態及數據存入到一個repository里去。
Repository
為了能夠做備份,我們首先必須創建一個repository,也就是一個倉庫。你可以為一個cluster創建多個倉庫。目前支持的倉庫類型有:
# Elasticsearch支持倉庫類型
Respository 配置類型
Shared file system "type": "fs"
Read-only URL "type": "url"
S3 "type": "s3"
HDFS "type": "hdfs"
Azure "type": "azure"
Google Cloud Storage "type": "gcs"
這里需要注意的是: S3, HDFS, Azure and GCS 需要相應的插件進行安裝才可以。
注冊倉庫
在一個snapshot可以被使用之前,我們必須注冊一個倉庫(repository)。
- 使用_snapshot 終點
- 文件夾必須對所有的node可以訪問
- path.repo必須在所有的node上進行配置,針對一個fs的repository來說
PUT _snapshot/my_repo
{
"type": "fs",
"settings": {
"location": "/mnt/my_repo_folder"
}
}
這里/mnt/my_repo_folder必須加進所有node的elasticsearch.yml文件中。
fs resposity設置:
PUT _snapshot/my_repo
{
"type": "fs",
"settings": {
"location": "/mnt/my_repo_folder",
"compress": true,
"max_restore_bytes_per_sec": "40mb",
"max_snapshot_bytes_per_sec": "40mb"
}
}
這里,我們定義compress為true,表明我們希望壓縮。通過max_restore_bytes_per_sec及max_snapshot_bytes_per_sec的定義,我們可以來限制數據的snapshot及恢復的數據速度。
S3 repository設置
為了能能使用S3倉庫,我們必須使用如下的命令來進行安裝插件:
./bin/elasticsearch-plugin install repository-s3
注意,上面的命令必須是在Elasticsearch的安裝目錄下進行執行。我們可以通過如下的命令來進行配置:
PUT _snapshot/my_s3_repo
{
"type": "s3",
"settings": {
"bucket": "my_s3_bucket_name"
}
}
這里的my_s3_bucket_name是我們在AWS上定義的S3 bucket。更多關於S3的配置可以參閱鏈接 Repository Settings(https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-repository.html)。
Snapshot所有的索引
一旦我們的repository已經被配置好了,那么我們就可以利用_snapshot終點來進行snapshot。必須注意的是snapshot只拷貝在執行該命令時的所有的數據,而在之后的所有的數據將不被備份。snapshot是按照增量來進行備份的,也就是說它只拷貝從上次執行snapshot之后變化的部分。通常來說,每隔30分鍾進行一次備份是足夠的。
snapshot命令:
PUT _snapshot/my_repo/my_snapshot_1
這里必須注意的幾點:
- my_repo是指的我們在上面定義的repository的名字
- my_snapshot_1指的是一個唯一的snapshot名字
- 沒有特定的索引名字被指出,那么它指的是所有的open索引
如果我們想指定某個或某些特定的索引,那么我們可以使用如下的命令來執行備份(snapshot)
PUT _snapshot/my_repo/my_logs_snapshot_1
{
"indices": "logs-*",
"ignore_unavailable": true,
"include_global_state": true
}
這里它表述我們相對所有以logs-為開頭的索引進行備份。
我們可以通過如下的命令來進行監測正在進行的snapshot的進度:
GET _snapshot/my_repo/my_snapshot_2/_status
管理snapshots
獲取所有在repo中的snapshots:
GET _snapshot/my_repo/_all
獲取某個特定snapshot的信息
GET _snapshot/my_repo/my_snapshot_1
刪除一個snapshot
DELETE _snapshot/my_repo/my_snapshot_1
恢復一個snapshot
我們可以使用_restore終點來從一個snapshot恢復所有的索引:
POST _snapshot/my_repo/my_snapshot_2/_restore
我們也可以通過如下的方法來恢復某個或某些特定的索引:
POST _snapshot/my_repo/my_snapshot_2/_restore
{
"indices": "logs-*",
"ignore_unavailable": true,
"include_global_state": false
}
在很多的時候,我們想把snapshot中的索引恢復到一個不同名字的索引之中,從而不用覆蓋現有的。我們可以通過rename_pattern及rename_replacement來進行配置:
POST _snapshot/my_repo/my_snapshot_2/_restore
{
"indices": "logs-*",
"ignore_unavailable": true,
"include_global_state": false,
"rename_pattern": "logs-(.+)",
"rename_replacement": "restored-logs-$1"
}
在上面,我們把所有的以logs-為開頭的索引恢復到以restored-logs-的開頭的索引之中來。
Restore到一個新的cluster
針對這個情況,我們可以恢復從另外一個cluster中備份的snapshot到當前的cluster中來。我們必須在新的cluster中注冊這個repository才可以進行下面的操作。
從上面我們可以看出來,my_repo必須對兩個cluster都是可見的才可以。
動手實踐
准備數據:
運行起來我們的Kibana:
我們分別點擊上面的1和2處:
點擊上面的“Add data”。這樣我們就可以把我們的kibana_sample_data_logs索引加載到Elasticsearch中。
GET _cat/indices/kibana_sample_data_logs
注冊repository
首先我們在我們的電腦上創建一個如下的目錄:
/shared_folder/my_repo
我們在termimal中打入如下的命令:
mkdir -p shared_folder/my_repo/
$ pwd
/Users/liuxg/shared_folder
bogon:shared_folder liuxg$ ls -al
drwxr-xr-x 2 liuxg staff 64 Nov 13 13:23 my_repo
將以下path.repo屬性添加到我們運行的所有node的elasticsearch.yml文件中:
path.repo: /Users/liuxg/shared_folder/my_repo
注意,針對你的情況,你需要改動這里的path路徑。
然后啟動我們的Elasticsearch及Kibana。緊接着,我們在Kibana console中打入如下的命令:
PUT _snapshot/my_local_repo
{
"type": "fs",
"settings": {
"location": "/Users/liuxg/shared_folder/my_repo"
}
}
注意這里的location是根據我自己的電腦的路徑來設置的。你需要根據自己實際的路徑進行修改。在這里my_local_repo是我們的repository名稱。
接下來,我們打入如下的命令來對我們的kibana_sample_data_logs索引進行snapshot:
PUT _snapshot/my_local_repo/snapshot_1
{
"indices": "kibana_sample_data_logs",
"ignore_unavailable": true,
"include_global_state": true
}
我們可以通過如下的命令來查看snapshot:
GET _snapshot/my_local_repo/_all
我們可以在右邊看到snapshot_1出現在列表之中,說明我們已經成功地創建了這個snapshot。
我們接下來可以通過如下的命令來刪除kibana_sample_data_logs索引:
DELETE kibana_sample_data_logs
這樣我們徹底地刪除了這個索引。那么我們該如何把之前備份的數據恢復回來呢?
在Kibana中打入如下的命令:
POST _snapshot/my_local_repo/snapshot_1/_restore
{
"indices": "kibana_sample_data_logs",
"ignore_unavailable": true,
"include_global_state": false
}
在執行完上面的命令后,我們可以通過如下的命令來查看恢復后的kibana_sample_data_logs索引:
GET kibana_sample_data_logs/_count
顯然我們已經成功地恢復了我們之前備份的數據。
這個時候,如果我們去到我們的snapshot文件目錄,我們可以看到:
$ pwd
/Users/liuxg/shared_folder/my_repo
bogon:my_repo liuxg$ ls
index-0 meta-TzygGpJ1SOK5yJdsmc1lng.dat
index.latest snap-TzygGpJ1SOK5yJdsmc1lng.dat
indices
顯然在文件目錄中,已經有新生產的文件了。