快照与灾难恢复

22 May 2026 – wusfe · 4 min read

快照与灾难恢复

一、Snapshot 是什么

Elasticsearch 的快照(Snapshot)是对集群索引的增量备份。第一次快照是完整备份,后续快照只备份自上次快照以来发生变化的 segment 文件。这个机制使得快照占用空间小、速度较快,适合高频备份策略。

快照存储在 Snapshot Repository(快照仓库)中,仓库是一个抽象层,底层可以是共享文件系统、对象存储等。

索引 segment 文件 → 快照仓库(FS / S3 / HDFS / GCS)→ 可恢复到任意集群

快照的粒度是索引级别,可以快照全部索引,也可以指定特定索引。

二、创建 Snapshot Repository

快照仓库的类型对比:

类型 适用场景 优点 缺点
FS (Shared File System) 自建机房,有 NFS 存储 配置简单 需要共享存储,所有节点都要可访问
S3 AWS 环境 可靠、便宜、自动扩展 仅 AWS,需要 S3 权限
GCS GCP 环境 同上 仅 GCP
Azure Azure 环境 同上 仅 Azure
HDFS 已有 Hadoop 生态 利用现有基础设施 依赖 Hadoop 集群

2.1 FS 仓库配置

# 在所有节点的 elasticsearch.yml 中添加
# path.repo: ["/mnt/es_backups", "/mnt/es_backups_2"]

# 然后通过 API 注册仓库
PUT /_snapshot/es_backup_repo
{
  "type": "fs",
  "settings": {
    "location": "/mnt/es_backups",
    "compress": true,
    "max_snapshot_bytes_per_sec": "50mb",
    "max_restore_bytes_per_sec": "50mb"
  }
}

参数说明:

  • compress:是否压缩元数据(默认 true),数据本身不压缩。
  • max_snapshot_bytes_per_sec:快照速度限制,避免影响线上写入性能。
  • max_restore_bytes_per_sec:恢复速度限制,同理。

2.2 S3 仓库配置

# 先安装 S3 repository 插件
# bin/elasticsearch-plugin install repository-s3

PUT /_snapshot/s3_backup_repo
{
  "type": "s3",
  "settings": {
    "bucket": "my-es-snapshots",
    "region": "ap-southeast-1",
    "base_path": "prod-cluster",
    "max_snapshot_bytes_per_sec": "100mb",
    "max_restore_bytes_per_sec": "100mb"
  }
}

三、创建与查看快照

3.1 创建快照

# 创建全集群快照
PUT /_snapshot/es_backup_repo/snapshot_20260521?wait_for_completion=true
{
  "indices": "orders-*,users",
  "ignore_unavailable": true,
  "include_global_state": true
}

# 异步创建(不等待完成,适合大集群)
PUT /_snapshot/es_backup_repo/snapshot_20260521_async
{
  "indices": "_all",
  "ignore_unavailable": true,
  "include_global_state": true
}

参数说明:

参数 说明
indices 要备份的索引,支持通配符
ignore_unavailable 索引不存在时是否报错(建议 true)
include_global_state 是否包含集群全局状态(索引模板、ILM 策略等)
wait_for_completion 是否同步等待完成

3.2 查看快照

# 查看所有快照
GET /_snapshot/es_backup_repo/_all

# 查看特定快照状态
GET /_snapshot/es_backup_repo/snapshot_20260521

# 查看正在进行的快照
GET /_snapshot/es_backup_repo/_current

3.3 删除快照

DELETE /_snapshot/es_backup_repo/snapshot_20260401

注意:快照是增量存储,删除旧快照不会影响后续快照的完整性——ES 会自动处理 segment 引用。

四、恢复快照

4.1 完整恢复

POST /_snapshot/es_backup_repo/snapshot_20260521/_restore
{
  "indices": "orders-2026",
  "ignore_unavailable": true,
  "include_global_state": false,
  "rename_pattern": "orders-(.+)",
  "rename_replacement": "restored_orders_$1"
}

4.2 恢复到新集群的场景

# 恢复前必须先关闭目标索引(如果已存在且有数据冲突)
POST /orders-2026/_close
POST /_snapshot/es_backup_repo/snapshot_20260521/_restore
{
  "indices": "orders-2026",
  "include_global_state": false
}

4.3 部分恢复(仅恢复特定分片数据)

POST /_snapshot/es_backup_repo/snapshot_20260521/_restore
{
  "indices": "orders-2026",
  "index_settings": {
    "index.number_of_replicas": 0
  },
  "ignore_index_settings": [
    "index.refresh_interval",
    "index.number_of_replicas"
  ]
}

五、SLM(Snapshot Lifecycle Management)自动快照

手动快照不可靠——一定会忘。SLM 是 ES 7.4+ 的内置功能,可自动定时创建快照并保留一定数量。

# 创建 SLM 策略:每天凌晨 2 点快照,保留最近 30 个
PUT /_slm/policy/daily_backup_policy
{
  "schedule": "0 30 2 * * ?",
  "name": "<daily-snap-{now/d}>",
  "repository": "es_backup_repo",
  "config": {
    "indices": ["orders-*", "users", "products-*"],
    "ignore_unavailable": true,
    "include_global_state": true
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 5,
    "max_count": 30
  }
}

# 查看 SLM 策略
GET /_slm/policy

# 查看 SLM 执行历史
GET /_slm/stats

# 手动执行一次 SLM 策略(验证用)
POST /_slm/policy/daily_backup_policy/_execute

六、恢复演练:核心中的核心

灾难恢复中最常见的错误:从来不做恢复演练。

很多团队每天都做快照,但从没验证过快照能不能用。等到真出事了,发现:

  • 快照仓库挂了,最近一个月的快照都是损坏的。
  • 快照不包含 include_global_state,索引模板和 ILM 策略全丢。
  • 恢复速度太慢,预估要 6 小时才能恢复完,业务等不了。

演练方案

# Step 1:定期(每月)将快照恢复到测试集群
POST /_snapshot/es_backup_repo/daily-snap-2026.05.20/_restore
{
  "indices": "orders-2026",
  "rename_pattern": "orders-(.+)",
  "rename_replacement": "drill_orders_$1",
  "include_global_state": false
}

# Step 2:验证恢复后的数据完整性
GET /drill_orders_2026/_count
GET /drill_orders_2026/_search
{
  "query": { "match_all": {} },
  "size": 10
}

# Step 3:演练结束后清理
DELETE /drill_orders_2026

七、备份频率建议

索引类型 备份频率 保留期 原因
核心交易索引(订单、支付) 每天 90 天 业务关键数据,绝对不能丢
日志索引 可选 7-14 天 通常有离线归档(Kafka),可从源头回放
搜索索引(商品、用户) 每天 30 天 可以从数据库重建,但有快照恢复更快
分析类索引 每周 30 天 数据可重新计算

八、踩坑案例

案例: 某团队使用 NFS 作为快照仓库,运行了半年一切正常。一次 SAN 网络故障导致 NFS 短暂不可达,恰好当时 SLM 策略正在执行快照——快照失败了,但 SLM 的 retention 策略仍在清理"过期"快照。结果 NFS 恢复后发现最近 3 天的快照全部丢失,而前一天恰好有索引误删除操作需要恢复。

教训:

  1. 快照仓库的存储可靠性优先于成本考虑——对象存储(S3)远比自建 NFS 可靠。
  2. retention 策略要考虑快照失败的场景,保留一定数量的快照兜底(min_count)。
  3. 快照失败要告警,不能静默失败。