概述
原理
ES底层核心基于lucene,一个分片即是一个lucene对象实例,ES快照(snapshot)本质是对lucene物理文件的拷贝。
增量快照的核心是比较lucene segements不可变文件信息,每次创建快照时会建立一个IndexCommit提交点,包含segmentsfilename(segment是lucene的不可变对象),在处理分片快照请求时会先查找分段文件是否存在,文件信息是存储在List<FileInfo>
对象中,如果文件信息存在,会比较checksum及hash值,如果都相同会跳过snapshot备份。否则会将该分片信息添加到本次快照的需要处理的全部文件列表。
仓库
在做任何快照操作前,必须得先有一个仓库,即快照存储在(快照)仓库下。建议为每个主版本创建一个仓库。有效的仓库设置取决于仓库类型。
如果多个集群注册同一个仓库,只有一个集群可以对仓库进行写操作,其他所有集群应该设置该仓库为readonly模式。
跨主版本时快照格式可能会改变,所以不同版本的集群写同一个快照仓库,某个版本写的快照可能对其他版本不可见,仓库快照也存在问题。ES不支持仓库对所有集群设置为readonly,其中一个集群和不同主版本的多个集群一起工作。
在所有主节点、数据节点上,需要配置elasticsearch.yml
文件,且报错配置一致,即路径位置一致:
path.repo: ["/data/es_snapshot"]
配置文件里,通过max_snapshot_bytes_per_sec
和max_restore_bytes_per_sec
来限制备份和恢复时速度,是全局生效的。同时支持某个特定仓库级别的速度,执行命令时以JSON参数形式放在RequestBody里。
给备份目录权限:chown -R es:es /data/es_snapshot
注册仓库my_backup
:
curl -X PUT 'http://localhost:9200/_snapshot/my_backup' -d '{
"type": "fs",
"settings": {
"location": "/data/es_snapshot",
"compress": true
}
}'
或:
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/data/es_snapshot",
"compress": true
}
当注册或更新仓库时,立即在所有主节点和数据节点上验证,以确保在集群中的所有节点上都可以使用。注册或更新快照仓库时不开启验证:PUT /_snapshot/s3_repository?verify=false
。手动执行命令验证仓库注册结果:POST /_snapshot/my_backup/_verify
。
type
指定类型,支持以下几种类型:
- fs:共享文件系统,将快照文件存放于文件系统中
- url:指定文件系统的URL路径,支持协议:http、https、ftp、file、jar。如果使用http、https、ftp三种协议,白名单设置
repositories.url.allowed_urls
参数,支持数组形式配置多个URL - s3:AWS S3对象存储快照存放于S3中,以插件形式支持
- hdfs:快照存放于hdfs中,插件
- cos:快照存放于腾讯云COS对象存储中,插件
type=fs
时,settings支持的参数:
- location:快照位置,必填
- compress:是否压缩。压缩仅适用于元数据文件,数据文件不进行压缩。默认值为true
-
chunk_size
:如果需要可以把大的文件分解成不同的快照。块的大小可以指定字节例如1G、10m、5K。默认值为null,表示无限的块大小 -
max_restore_bytes_per_sec
:每个节点的恢复速度。默认值为40MB每秒 -
max_snapshot_bytes_per_sec
:每个节点生成的快照速度。默认值为40MB每秒 - readonly:使存储库只读,默认为false
type
设置为其他类型时,setting参数不完全一致,如type=s3
,支持参数bucket、region。
查看注册仓库:GET _snapshot/
操作
创建快照
创建快照时,默认会备份所有已打开的索引,包括备份系统自带的以点号开头的索引,如.kibana
、.security
、.monitoring
等,不建议备份系统自带索引,会占用较大空间。
PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true
命令会为所有打开的索引创建名称为snapshot_1
的快照,并保存到my_backup
仓库中。该命令会立刻返回,并在后台执行备份任务。如果您希望任务执行完成后再返回,添加wait_for_completion实现。该参数会阻塞调用直到备份完成,如果是大型快照,需要很长时间才能返回。
一个仓库可以包含多个快照,每个快照中可以包含所有、部分或单个索引的备份数据。
第一次创建快照时,系统会备份所有的数据,后续所有的快照仅备份已存快照和新快照之间的增量数据。随着快照的不断进行,备份也在增量的添加和删除。这意味着后续备份会相当快速,因为它们只传输很小的数据量。
命令指定需要备份的一个或多个索引:
PUT _snapshot/my_backup/snapshot_1
{
"indices": "index_1, index_2",
"ignore_unavailable": "true",
"include_global_state": false
}
- indices:可以使用支持多索引语法的索引参数来指定快照的索引列表。
-
ignore_unavailable
,不设置或设置为false时,如果不存在索引,索引快照请求将失败;设置为true时,在快照创建过程中忽略不存在的索引。 -
include_global_state
:为false可以防止集群全局状态被存储为快照的一部分。默认情况下,如果有一个或多个索引没有可用的主分片,整个快照会失败,这种行为可以通过设置部分来改变。
索引快照处理是渐进的。在索引快照的过程中ES会分析索引文件的列表是否已存储在存储库中,同时复制上次创建的快照或更改的文件。这允许在一个紧凑形式的存储库中保存多个快照,快照的过程是非阻塞的方式执行。当对索引正在执行快照时,所有的索引和搜索操作可以继续执行。然而,快照执行的数据是在快照创建时的时间点确定的,所以在快照过程开始后添加到索引中的记录将不会在快照中出现。在1.2.0版本之前,如果集群有迁移或者在索引中初始化分片时会失败,在1.2.0之后,快照的操作会等待这些完成后再操作。一个快照除了创建集群的副本外,还可以存储全局集群元数据,其中包括持久性集群设置和模板。临时设置和注册的快照库不会存储为快照的一部分。在任何时间只有一个快照过程在集群中被执行。而对快照创建分片时,这分片不能移动到另一个节点,它可能干扰平衡过程和过滤操作。一次快照操作只能移动一块到另一个节点(根据当前配置过滤设置和调整算法)。
对应的源码为:RestCreateSnapshotAction
查询快照
# 查看所有快照
GET _snapshot/my_backup/_all
# 查看指定的一个或多个快照,支持通配符
GET _snapshot/my_backup/snapshot_*, other_snapshot
# 查询当前正在运行的快照
GET _snapshot/my_backup/_current
# 根据快照名查看指定快照
GET _snapshot/my_backup/snapshot_1
# 使用_status API查看指定快照
GET _snapshot/_status
GET /_snapshot/my_backup/_status
GET _snapshot/my_backup/snapshot_1/_status
对应的源码为:RestGetSnapshotsAction
删除快照
命令DELETE _snapshot/my_backup/snapshot_1
删除指定的快照。如果该快照正在进行,系统会中断快照进程并删除仓库中创建到一半的快照。
删除快照请使用DELETE API,而不能使用其他机制删除(例如手动删除可能会造成备份严重损坏)。因为快照是增量的,很多快照可能依赖于之前的备份数据。DELETE API能够过滤出还在被其他快照使用的数据,只删除不再被使用的备份数据。
当快照从库中删除时,ES将删除与快照关联的和其他快照也不使用的所有文件。如果执行快照创建的过程中同时删除快照,则快照创建的过程会停止,同时删除相关的文件。因此,删除快照操作可以用来取消被错误启动的长时间运行的快照操作。
对应的源码为:RestDeleteSnapshotAction.java
删除快照,主要发送的请求是deleteSnapshotRequest,对请求的处理也是先构建request,发送到任意节点,节点再将请求发送到master节点,master节点会先获取仓库中快照信息,找到需要删除的仓库快照,提交更新集群状态任务,对于正在进行中的快照任务,将其标记为ABORTED状态,其他数据节点监听集群状态变更事件,最终调用底层的shardContainer.deleteBlobsIgnoringIfNotExists(blobsToDelete);
删除仓库中的快照数据。
删除存储库:DELETE _snapshot/my_backup
。当一个库被删除,ES仅删除存储库位置的引用,快照本身并没有被删除。
对应的源码为:RestDeleteRepositoryAction
恢复快照
知识点
- 建议不要恢复
.
开头的系统索引,此操作可能会导致Kibana访问失败等问题 - 如果集群中存在与待恢复索引同名的索引,需提前删除或关闭该同名索引后再恢复,否则恢复失败
- 快照是增量的,存在在多个可能不兼容(升级)的ES版本中创建的索引。故快照恢复不一定能成功
- 跨集群恢复时,目标ES集群的主版本号(Major.Minor.Patch中的Major)要大于等于源ES集群的主版本号。特别地,1.x版本的集群创建的快照不能在5.x版本中恢复
- 如果需要跨地域恢复集群快照,需要先将原地域OSS中的快照数据迁移到目标地域的OSS中,再恢复到目标地域的ES集群中
如果需要恢复一个与你当前运行的集群版本不兼容的索引快照,你可以先恢复到最新的兼容版本中,然后在当前版本中使用reindex-from-remote
重建索引。远程Reindexing只能在源索引source为enabled的情况下进行。获取并重建数据索引的时间可能比简单恢复快照要长的多。如果你的数据量较大,建议先用一部分数据测试远程reindex,以便了解需要花费的时间
恢复所有索引:POST _snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true
。_restore API会立刻返回,恢复进程会在后台进行。
恢复索引时可通过-
指定排除某些索引:
POST _snapshot/my_backup/snapshot_1/_restore
{
"indices": "*,-.security*,-.kibana*",
"ignore_unavailable": "true"
}
恢复指定索引:
POST /_snapshot/my_backup/snapshot_1/_restore
{
"indices": "index_1",
"ignore_unavailable": "true",
"include_global_state": false
"rename_pattern": "index_(.+)",
"rename_replacement": "restored_index_$1"
}
参数 | 说明 |
---|---|
indices | 指定恢复的索引,忽略快照中的其他索引 |
rename_pattern | 查找待恢复的索引模式 |
rename_replacement | 重命名 |
问题:indices和rename_pattern参数互相冲突时怎么办?
删除正在恢复的索引,取消恢复操作:DELETE /restored_index_3
对应的源码为:RestRestoreSnapshotAction
恢复进度
通过_recovery API来监控快照恢复的状态、进度等信息。
查看快照中指定索引的恢复状态:GET restored_index_3/_recovery
查看集群中的所有索引的恢复信息:GET /_recovery/
文章来源:https://www.toymoban.com/news/detail-858989.html
其他
如果集群启用安全功能,则在备份数据时必须授权快照API调用。文章来源地址https://www.toymoban.com/news/detail-858989.html
参考
- ElasticSearch技术解析与实战
到了这里,关于ES系列之快照与恢复的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!