ES系列之快照与恢复

概述

原理

ES底层核心基于lucene,一个分片即是一个lucene对象实例,ES快照(snapshot)本质是对lucene物理文件的拷贝。

增量快照的核心是比较lucene segements不可变文件信息,每次创建快照时会建立一个IndexCommit提交点,包含segmentsfilename(segment是lucene的不可变对象),在处理分片快照请求时会先查找分段文件是否存在,文件信息是存储在List<FileInfo>对象中,如果文件信息存在,会比较checksum及hash值,如果都相同会跳过snapshot备份。否则会将该分片信息添加到本次快照的需要处理的全部文件列表。

仓库

在做任何快照操作前,必须得先有一个仓库,即快照存储在(快照)仓库下。建议为每个主版本创建一个仓库。有效的仓库设置取决于仓库类型。

如果多个集群注册同一个仓库,只有一个集群可以对仓库进行写操作,其他所有集群应该设置该仓库为readonly模式。

跨主版本时快照格式可能会改变,所以不同版本的集群写同一个快照仓库,某个版本写的快照可能对其他版本不可见,仓库快照也存在问题。ES不支持仓库对所有集群设置为readonly,其中一个集群和不同主版本的多个集群一起工作。

在所有主节点、数据节点上,需要配置elasticsearch.yml文件,且报错配置一致,即路径位置一致:

yml 复制代码
path.repo: ["/data/es_snapshot"]

配置文件里,通过max_snapshot_bytes_per_secmax_restore_bytes_per_sec来限制备份和恢复时速度,是全局生效的。同时支持某个特定仓库级别的速度,执行命令时以JSON参数形式放在RequestBody里。

给备份目录权限:chown -R es:es /data/es_snapshot

注册仓库my_backup

shell 复制代码
curl -X PUT 'http://localhost:9200/_snapshot/my_backup' -d '{
	"type": "fs",
	"settings": {
		"location": "/data/es_snapshot",
		"compress": true
	}
}'

或:

shell 复制代码
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实现。该参数会阻塞调用直到备份完成,如果是大型快照,需要很长时间才能返回。

一个仓库可以包含多个快照,每个快照中可以包含所有、部分或单个索引的备份数据。

第一次创建快照时,系统会备份所有的数据,后续所有的快照仅备份已存快照和新快照之间的增量数据。随着快照的不断进行,备份也在增量的添加和删除。这意味着后续备份会相当快速,因为它们只传输很小的数据量。

命令指定需要备份的一个或多个索引:

js 复制代码
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会立刻返回,恢复进程会在后台进行。

恢复索引时可通过-指定排除某些索引:

js 复制代码
POST _snapshot/my_backup/snapshot_1/_restore 
{
    "indices": "*,-.security*,-.kibana*",
    "ignore_unavailable": "true"
}

恢复指定索引:

js 复制代码
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/

其他

如果集群启用安全功能,则在备份数据时必须授权快照API调用。

参考

  • ElasticSearch技术解析与实战
相关推荐
徐*红2 小时前
Elasticsearch 8.+ 版本查询方式
大数据·elasticsearch
码爸3 小时前
flink 例子(scala)
大数据·elasticsearch·flink·scala
txtsteve3 小时前
es由一个集群迁移到另外一个集群es的数据迁移
大数据·elasticsearch·搜索引擎
工作中的程序员3 小时前
ES 索引或索引模板
大数据·数据库·elasticsearch
Lill_bin15 小时前
深入理解ElasticSearch集群:架构、高可用性与数据一致性
大数据·分布式·elasticsearch·搜索引擎·zookeeper·架构·全文检索
RwTo17 小时前
Elasticsearch 聚合搜索
大数据·elasticsearch·搜索引擎·全文检索
求学小火龙18 小时前
ElasticSearch介绍+使用
java·大数据·elasticsearch
檀越剑指大厂18 小时前
【Elasticsearch系列六】系统命令API
大数据·elasticsearch·搜索引擎
bug菌¹1 天前
滚雪球学SpringCloud[5.1讲]: Spring Cloud Config详解
spring·elasticsearch·spring cloud
Li小李同学Li1 天前
git学习【持续更新中。。。】
git·学习·elasticsearch