快照与灾难恢复
快照与灾难恢复
一、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 天的快照全部丢失,而前一天恰好有索引误删除操作需要恢复。
教训:
- 快照仓库的存储可靠性优先于成本考虑——对象存储(S3)远比自建 NFS 可靠。
- retention 策略要考虑快照失败的场景,保留一定数量的快照兜底(
min_count)。 - 快照失败要告警,不能静默失败。