系统学习 学习路径总入口:先选领域,再建立模型,最后用故障演练验证

用快照仓库把 Elasticsearch 索引和集群元数据恢复到确定时点,并验证、切换或回滚

适用场景

Elasticsearch 的副本不是备份,副本只能应对节点故障,无法恢复误删和逻辑损坏。快照是增量的,多个快照之间共享 segment,快照仓库必须独立于集群数据盘,并且不能被手工清理。快照不保证所有索引的写入严格同时刻;需要强一致时先停止写入并确认刷新。

恢复前要明确 RPO:能接受回到哪一次成功快照。快照之后的写入不会自动补回,需要从上游数据、事务日志或消息队列另行补偿。

前置检查

  1. 明确恢复范围。列出要恢复的索引、别名、模板、ILM 和 pipeline,并确认是恢复到原集群、新集群,还是先做隔离验证。

  2. 确认快照仓库和快照可用:

curl -s 'http://es:9200/_snapshot?pretty'
curl -s 'http://es:9200/_cat/snapshots/<repo>?v'
curl -s 'http://es:9200/_snapshot/<repo>/<snap>?pretty'
curl -s 'http://es:9200/_snapshot/<repo>/<snap>/_status?pretty'
curl -s -X POST 'http://es:9200/_snapshot/<repo>/_verify?pretty'

重点看快照的 state、起止时间、包含的索引、成功和失败的分片数。SUCCESS 且失败分片为 0 才适合直接恢复;PARTIAL 或存在失败分片时,先判断缺的是否是关键索引,不要默认它可用。_verify 只验证仓库访问和基本可用性,不等于每个分片都可读,仍要结合 _status 和恢复日志。

  1. 检查仓库类型和凭据。fs 仓库要求所有节点配置相同的 path.repo 并有读写权限;对象存储仓库要确认桶、前缀、凭据、网络和生命周期规则。快照仓库不能和集群数据放在同一块盘上,否则磁盘故障会同时丢失生产和备份。仓库对象不要手工删除,多个快照共享 segment。

  2. 检查目标集群。确认版本兼容,节点数、磁盘空间、分片上限、watermark 和副本规划能容纳恢复后的索引。空间不足时索引可能恢复成功但副本长期未分配。

curl -s 'http://es:9200/_cluster/health?pretty'
curl -s 'http://es:9200/_cat/nodes?v'
curl -s 'http://es:9200/_cat/allocation?v'
curl -s 'http://es:9200/_cat/indices?v'
  1. 保留现场和回滚路径。记录当前索引、别名、模板、ILM、pipeline 和集群设置;条件允许时先拍一份当前状态的新快照。恢复时优先使用重命名恢复到临时索引,不要直接覆盖生产索引。
curl -s 'http://es:9200/_cat/indices?v' > indices-before.txt
curl -s 'http://es:9200/_cat/aliases?v' > aliases-before.txt
curl -s 'http://es:9200/_index_template?pretty' > templates-before.json
curl -s 'http://es:9200/_ilm/policy?pretty' > ilm-before.json
curl -s 'http://es:9200/_ingest/pipeline?pretty' > pipelines-before.json
  1. 冻结写入并暂停自动化。停止应用写入、Logstash/Filebeat 等采集端和批量导入任务;暂停 ILM 和 SLM,避免恢复过程中策略删除或滚动索引:
curl -s -X POST 'http://es:9200/_ilm/stop?pretty'
curl -s -X POST 'http://es:9200/_slm/stop?pretty'

如果集群启用了 transform、CCR 或 rollup,也要暂停,避免它们在恢复窗口继续写索引。

恢复步骤

1. 选择恢复粒度

只恢复数据索引时,保持 include_global_state 为 false,避免把旧模板、旧 ILM 策略和旧集群设置覆盖到当前集群。需要同时恢复模板、pipeline、ILM 等集群级元数据时,再评估是否使用 include_global_state=true;它可能覆盖目标端较新的配置,恢复后要逐项对比。

恢复部分索引时,用 indices 指定名称或通配符,并设置 ignore_unavailable=true,避免快照中缺少某个索引导致整个请求失败。不要用 partial=true 作为常规选项,它只恢复可用分片,可能留下缺少主分片的索引。

2. 恢复到临时索引

优先使用重命名,把快照中的索引恢复到新名称,验证通过后再切换别名:

curl -s -X POST 'http://es:9200/_snapshot/<repo>/<snap>/_restore?wait_for_completion=false&pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "indices": "orders-*",
    "ignore_unavailable": true,
    "include_global_state": false,
    "include_aliases": false,
    "rename_pattern": "(.+)",
    "rename_replacement": "restored-$1"
  }'

恢复请求默认异步执行,返回 accepted 只表示任务已提交。持续观察恢复进度和集群状态:

curl -s 'http://es:9200/_cat/recovery?v&active_only=true'
curl -s 'http://es:9200/_snapshot/<repo>/<snap>/_status?pretty'
curl -s 'http://es:9200/_cluster/health?pretty'
curl -s 'http://es:9200/_cat/shards?v' | grep -E 'UNASSIGNED|INITIALIZING'

如果目标集群磁盘接近 watermark,先清理空间或扩容;否则分片可能无法分配。恢复并发过高时,可调整 cluster.routing.allocation.node_concurrent_recoveries 和 indices.recovery.max_bytes_per_sec,但不要为了追求速度把节点压垮。

3. 同名索引的恢复

同名索引处于 open 状态时,直接恢复通常会因索引已存在而失败。可选做法只有两类:先关闭或删除旧索引再恢复,或恢复到临时名称后用别名切换。删除前必须确认已有可用快照和回滚路径,不能用“删了再试”处理生产索引。

如果新索引的 mapping 与旧索引不兼容,不能原地修改已有字段类型。应恢复到临时索引,确认新 mapping 后用 _reindex 重建,或让应用写新索引;_reindex 会额外占用磁盘和时间,数据量大时要先评估。

4. 恢复集群级元数据

需要恢复模板、ILM、pipeline 时,先确认目标端是否有更新的版本。可以把快照恢复到隔离集群导出配置,再逐项对比后写入生产,而不是直接打开 include_global_state 覆盖。恢复顺序通常是:组件模板和索引模板、ILM 策略、ingest pipeline、索引数据、别名。

用户、角色、API key、TLS 证书等安全配置不要只依赖索引快照,应单独备份并在目标集群验证。快照中的数据可能包含敏感信息,仓库要启用加密和最小权限访问。

5. 切换与恢复写入

验证完成后,用别名原子切换。下面把读流量从旧索引切到恢复索引,旧索引先保留,确认无误后再删除:

curl -s -X POST 'http://es:9200/_aliases?pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "actions": [
      {"remove": {"index": "orders-current", "alias": "orders"}},
      {"add": {"index": "restored-orders-current", "alias": "orders"}}
    ]
  }'

切换前确认写别名只指向一个索引,避免双写;如果应用直接写具体索引名而不是别名,要先改配置或重建索引名。切换后恢复 ILM/SLM 和采集端,观察写入、刷新、段合并和副本分配,再补拍一份新快照:

curl -s -X POST 'http://es:9200/_ilm/start?pretty'
curl -s -X POST 'http://es:9200/_slm/start?pretty'
curl -s -X PUT 'http://es:9200/_snapshot/<repo>/post-restore-<date>?wait_for_completion=false&pretty'

验证

失败与回滚

快照不存在或仓库不可访问。 先检查仓库注册、凭据、网络和对象存储生命周期,确认快照没有被清理。不要反复重建仓库指向同一个错误路径;换一个已知可用的快照验证仓库本身。

快照分片失败或状态为 PARTIAL。 先确认缺失的分片是否属于关键索引。能重新拍摄就重拍;不能重拍时,评估是否接受部分数据,并把缺失范围写进事故记录。不要把 partial=true 的结果当成完整恢复。

版本或插件不兼容。 目标集群版本不能低于快照来源,跨大版本要先在隔离环境验证。快照格式不兼容时,只能升级目标集群或从兼容的来源重建,不能通过改配置强行读取。

恢复卡住或分片长时间 INITIALIZING。 查看 _cat/recovery、_cluster/allocation/explain、磁盘 watermark、节点容量和仓库吞吐。先解决分配阻塞,再调整恢复并发;不要靠重启所有节点“碰运气”。

mapping 冲突。 已有字段类型不能原地修改。恢复到新索引后用 _reindex 重建,或在应用层做字段转换;不要删除生产索引来强行套用旧 mapping。

ILM 删除了恢复出的索引。 立即停止 ILM,确认策略匹配和索引生命周期状态,必要时从快照重新恢复。恢复前暂停 ILM 是避免该问题的前置条件,不是恢复后的补救措施。

需要回滚。 保留旧索引、旧别名和恢复前的快照;如果新索引已经接受写入,先停止写入,评估差异后再切回。不能简单把别名切回旧索引而忽略新写入,否则会丢数据或造成两份不一致的数据。

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. Elasticsearch 快照是增量的,为什么仍不能手工删除仓库中的对象?
  2. 恢复同名生产索引时,为什么优先恢复到临时索引并切换别名?
  3. include_global_state=true 有什么风险,恢复前应怎样处理 ILM 和 SLM?
答案
  1. 多个快照共享 segment,手工删除仓库对象可能破坏其他快照的引用;应通过快照 API 和生命周期策略管理,并保证仓库独立、可访问。
  2. 同名 open 索引会让恢复失败,直接关闭或删除旧索引又缺少验证和回滚空间;恢复到临时索引可以先核对文档数、mapping 和查询结果,再用别名原子切换,旧索引保留到确认完成。
  3. 它可能用旧快照覆盖目标集群的模板、ILM 策略、pipeline 等元数据;应先对比目标配置,必要时在隔离集群导出后逐项恢复,并在恢复前暂停 ILM/SLM,避免策略删除或滚动恢复中的索引。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令