ES的快照是什么?
snapshot是一个ES集群或者某个指定索引的备份,快照一般用在
- 不停机的状态下对ES集群进行备份
- 当硬件故障时恢复集群数据
- 用于跨集群的数据迁移
- 对冷数据或冻结数据做快照以降低存储成本,依赖于可搜索的快照。-收费功能
一个快照包含的内容:
- 持久的集群配置
- 索引模板
- 索引数据
- 索引生命周期策略
- 存储的脚本
- 预处理流水线
ES快照的原理
ES快照的过程就是将指定索引(也可以是整个集群)在磁盘上存储的Lucene文件复制到仓库中。
以一个索引为例,当快照这个索引时,会根据快照时间复制一份这个索引所有segments文件到仓库中,快照未完成前,这些物理文件不可删除,不可移动。如果这个快照是第一次创建,快照时会复制这个索引全部的segments文件;在这之后,再次快照这个索引的内容时,只会复制较上一次快照时新增的segments文件。
除第一次之后的快照都是增量。
快照文件之间在逻辑上独立,当删除一个快照时,只会从库中删除这个所独有的segment文件,而不会删除有其他快照使用的文件。
快照过程中会锁定所有涉及到的segment文件,快照进行中的索引无法迁移分片且segment不可删除。且数据复制只发生在主分片上。
创建快照
创建快照前首行需要注册快照仓库。
查看当前集群的仓库
GET /_cat/repositories
注册快照仓库
快照仓库所支持的类型:
- fs 文件系统(这里需要共享文件系统)
- s3 aws s3协议存储
- gcs 谷歌存储
- Read-only Url
这里列s3和fs两种仓库的注册案例:
s3对象存储
PUT _snapshot/my_s3_repository
{
"type": "s3",
"settings": {
"client": "my-client",
"bucket": "my-bucket",
"endpoint": "my.s3.endpoint"
///待补充其他参数
}
}
S3 repository | Elasticsearch Guide [8.14] | Elastic
S3案例:
PUT _snapshot/recovery_snapshot
{
"type" : "s3",
"settings" : {
"bucket" : "",
"base_path" : "",
"endpoint" : "",
"protocol" : "http",
"compress" : "true",
"access_key": "",
"secret_key": "",
"max_restore_bytes_per_sec" : "200mb",
"max_snapshot_bytes_per_sec" : "100mb"
}
}
fs文件系统
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/mount/backups/backup" #这个路径需要提前在配置文件中配置好
}
}
read-only url 只读库
使用url文件在集群上注册一个只库的快照仓库:
PUT _snapshot/my_backup_read_only
{
"type": "url",
"settings": {
"url": "file:/mount/backups/my_fs_backup_location" #样例为共享文件系统
}
}
url 支持的类型
- file
- http
- https
- jar
使用file类型的url时,file后的路径必须在es的配置文件path.repo配置项中指定。其他几个不需要。
创建一个快照
通过api创建一次性的快照
PUT /_snapshot/my_backup/back_snapshot_1
{
"indices": "index1,index2", #支持多索引语法,如通配符、列表
"ignore_unavailable": true, #跳过不存在的索引,默认为false
"include_global_state": false #不快照集群状态,默认为false
}
通过快照生命周期管理创建快照
如果用快照来定期备份ES集群的数据,使用快照生命周期策略来创建、管理快照。参考附录
#全量快照
PUT _slm/policy/s-01
{
"schedule": "0 0/15 * * * ?",
"name": "<my-snap-{now/d}>",
"repository": "my_backup",
"config": {
"indices": "*",
"include_global_state": true
},
"retention": {
"expire_after": "3d",
"min_count": 5,
"max_count": 50
}
}
使用快照
快照的作用一般用于数据备份、故障恢复、跨集群的数据迁移。
集群内
无论快照用于处理以上哪种情况,快照最终都是在某个集群内部通过restore恢复数据来发挥作用,快照的恢复过程如下:
- 查看当前的集群有哪些快照文件
GET _snapshot
#明确哪个仓库的情况下指定仓库名
GET _cat/snapshots/my_backup
#或
GET _snapshot/my_backup/*?verbose=false
- 恢复前从集群内删除要恢复的索引,避免冲突
DELETE index_1
- 从快照恢复index_1的数据
POST _snapshot/my_backup/my_snapshot_2099.05.06/_restore
{
"indices": "index_1" #如果快照中是多个索引,这里可以指定要恢复的列表,逗号分隔
}
如不删除现有数据时,可以在恢复时修改索引名。
POST _snapshot/my_backup/my_snapshot_2099.05.06/_restore
{
"indices": "index_1",
"ignore_unavailable": true,
"include_global_state": false,
"rename_pattern": "index_(.+)", #匹配要修改索引名的索引
"rename_replacement": "my_test_$1", #修改索引名称
"include_aliases": false
}
- 查看快照恢复过程
快照恢复过程中,会涉及到分片的复制和分配,恢复过程中,集群状态会出现yellow状态。
#查看集群状态
GET _cluster/health
查看恢复的详情
GET index_1/_recovery
查看分片的状态
GET _cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state
恢复完成后,集群转为green状态。
撤回一个restore
可以通过删除索引的方式,取消正在进行的恢复过程。
DELETE index_1
跨集群(跨版本)
在ES集群迁移或者索引跨集群迁移时,需要把一个集群中的快照在另外一个集群中恢复出来。这里需要注册原集群的仓库到新的集群中,如果原集群还在往这个仓库写数据,在新的集群中需要注册为只读库。
注册完仓库后,其他操作与集群内的快照恢复操作一致。
恢复前需要确保新的集群有充足的存储空间。
POST _snapshot/my_backup_read_only/my_snapshot_2099.05.06/_restore
{
"indices": "index_1" #如果快照中是多个索引,这里可以指定要恢复的列表,逗号分隔
}
如果快照中索引是多副本,且不想调整新集群的规格,可以在恢复时调整副本数以节省存储空间。
POST _snapshot/my_backup_read_only/my_snapshot_2099.05.06/_restore
{
"indices": "index_1",
"index_settings": {
"index.number_of_replicas": 1 #减少副本数以节省空间
}
}
快照跨版本的兼容性
如果新集群与老集群版本不一致,需要保证两个版本的快照兼容性,如下图:
删除快照
对于过期的快照,或者不再使用的快照,可以手动从仓库中删除:
DELETE /_snapshot/my_backup/snapshot_1
因快照时间过长,需要停止正在进行的快照?
快照和数据恢复设计只允许同时一个快照进程,或者恢复进程。如果快照执行过程出错,或长时间未结束而需要中止快照进程,可以执行删除快照的动作。删除操作会首先检查快照是否正在进行中,如果正在执行,会先停止快照,然后再把快照文件从库中删除。
附录:
SLM(快照生命周期管理)
快照生命周期管理 (公有云上公开发售的es版本不支持)
当快照作为一个集群集群的常规备份手段时,再每次写脚本加定时任务的形式去创建快照并且还需要不定期去处理过期的快照文件便显得不是很友好。自7.6版本起,es引入了快照生命周期管理(slm)的功能,类似于ilm(索引生命周期管理)。
slm可以通过简单的配置实现规律的创建快照,并根据预设条件删除符合条件的快照文件。 实现对快照创建、删除等整个生命周期的管理。
slm可以通过kibana界面进行新建:Stack Management > Snapshot and Restore > Policies。
通过api创建
- 查询集群现有slm策略
GET _slm/policy/{policy-id} #指定策略
GET _slm/policy
- 创建一条策略
PUT /_slm/policy/daily-snapshots
{
"schedule": "0 30 1 * * ?", # 什么时间创建快照
"name": "<daily-snap-{now/d}>", #快照名称
"repository": "my_repository", #使用的快照仓库
"config": {
"indices": ["data-*", "important"], #快照包含哪些索引
"ignore_unavailable": false,
"include_global_state": false
},
"retention": {
"expire_after": "30d", #快照保存多长时间
"min_count": 5, #最少保留几个版本,不受保存时间限制
"max_count": 50 #最多保存多少个文件,不受保存时间约束
}
}
schedule时间设置格式
<seconds> <minutes> <hours> <day_of_month> <month> <day_of_week> [year]
秒 分 小时 天 月 星期几? 哪年
?表示任意一[秒|分|时|天|月|星期几|年]
- 删除一条策略
DELETE /_slm/policy/daily-snapshots
- 立即执行策略
POST /_slm/policy/daily-snapshots/_execute
- 显示策略统计信息
GET /_slm/stats
命令汇总
#查看当前仓库
GET /_cat/repositories
#注册仓库
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/mnt/es/repo"
}
}
#注册url只读库
PUT _snapshot/my_backup_read_only
{
"type": "url",
"settings": {
"url": "file:/mount/backups/my_fs_backup_location"
}
}
#创建快照
PUT /_snapshot/my_backup/back_snapshot_1
{
"indices": "index1,index2",
"ignore_unavailable": true,
"include_global_state": false
}
#查看快照
GET _snapshot
#明确哪个仓库的情况下指定仓库名
#
GET _cat/snapshots/my_backup
#
GET _snapshot/my_backup/*?verbose=false
#获取所有快照信息
#查看当前正在进行中的快照
GET /_snapshot/my_backup/_current
#删除索引
DELETE index_1
#从快照恢复数据
POST _snapshot/my_backup/my_snapshot_2099.05.06/_restore
{
"indices": "index_1"
}
#从快照恢复索引,并修改索引名称
POST _snapshot/my_backup/my_snapshot_2099.05.06/_restore
{
"indices": "index_1",
"ignore_unavailable": true,
"include_global_state": false,
"rename_pattern": "index_(.+)", #匹配要修改索引名的索引
"rename_replacement": "my_test_$1", #修改索引名称
"include_aliases": false
}
#查看恢复详情
GET index_1/_recovery
#查看恢复中的分片状态
GET _cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state
#撤销进行的restore
DELETE index_1
#删除快照
DELETE /_snapshot/my_backup/snapshot_1
#slm相关
GET _slm/policy
#
PUT /_slm/policy/daily-snapshots
{
"schedule": "0 30 1 * * ?",
"name": "<daily-snap-{now/d}>",
"repository": "my_repository",
"config": {
"indices": ["data-*", "important"],
"ignore_unavailable": false,
"include_global_state": false
},
"retention": {
"expire_after": "30d",
"min_count": 5,
"max_count": 50
}
}
#
DELETE /_slm/policy/daily-snapshots
#
POST /_slm/policy/daily-snapshots/_execute
#
GET /_slm/stats
#
GET _slm/status
#
POST _slm/start
#
POST _slm/stop
#
POST /_slm/_execute_retention