这是《Elasticsearch 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 高可用不是“副本数设置为 2”这么简单。它包含节点冗余、分片分布、机架感知、快照备份、跨机房容灾、容量规划、滚动升级和故障演练。容量治理则回答:现在够不够、多久会不够、扩容后是否仍然安全。
32.1 可用性目标
先定义业务目标:
| 场景 | RPO | RTO | 建议架构 |
|---|---|---|---|
| 商品搜索 | 分钟级同步 | 5-15 分钟 | 多节点、可重建索引 |
| 日志检索 | 可容忍队列缓冲 | 15-30 分钟 | Kafka 削峰、多节点 |
| 订单分析 | 分钟级 | 30 分钟 | 主数据源可重建 |
| 安全审计 | 近零丢失 | 依合规要求 | 独立集群、快照、远程备份 |
关键概念:
- RPO:最多丢多少数据;
- RTO:最多多久恢复;
- MTTR:平均恢复时间;
- SLO:可用性目标;
- error budget:允许的不可用预算。
如果搜索索引可以从主数据源重建,架构会比把 ES 当最终数据库更从容。
32.2 节点与分片冗余
基本要求:
- 3 个 master-eligible 节点;
- data 节点至少 3 个;
- 副本至少 1 个;
- 副本与主分片不在同一节点;
- 同一物理机、机架或可用区不承载同一分片多个副本;
- 磁盘保留足够余量。
机架感知:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.awareness.attributes": "rack_id"
}
}
强制感知:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.awareness.attributes": "zone",
"cluster.routing.allocation.awareness.force.zone.values": "zone-a,zone-b"
}
}
节点配置属性:
node.attr.zone: zone-a
如果配置强制感知但节点只在单 zone,分片可能保持未分配。必须先确认拓扑,再调整 awareness。
32.3 延迟分配
节点短暂离开时,可以延迟副本分配,避免不必要恢复:
PUT /_all/_settings
{
"index.unassigned.node_left.delayed_timeout": "10m"
}
查看延迟分片:
GET /_cluster/health
关键字段:
delayed_unassigned_shards;number_of_nodes;unassigned_shards。
适合网络抖动或计划内短暂重启。如果节点确定不会恢复,应手动触发分配或扩容,而不是无限等待。
32.4 快照备份
快照是应对误删除、逻辑损坏和机房级故障的基础。
注册仓库:
PUT /_snapshot/backup-repo
{
"type": "s3",
"settings": {
"bucket": "es-backup",
"region": "cn-north-1",
"base_path": "prod",
"chunk_size": "1gb",
"max_restore_bytes_per_sec": "200mb",
"readonly": false
}
}
验证仓库:
POST /_snapshot/backup-repo/_verify
创建快照:
PUT /_snapshot/backup-repo/snapshot-2026.08.25?wait_for_completion=false
{
"indices": "products-v3,orders-v3,logs-*",
"include_global_state": false,
"partial": false
}
查看:
GET /_snapshot/backup-repo/snapshot-2026.08.25
GET /_snapshot/backup-repo/_current
删除快照:
DELETE /_snapshot/backup-repo/snapshot-2026.08.25
治理要求:
- 每日快照,关键索引可更频繁;
- 快照仓库开启版本控制和只读副本;
- 备份异地保存;
- 定期恢复演练;
- 监控成功率和耗时;
- 明确保留策略;
- 快照桶权限独立。
32.5 恢复
查看可恢复快照:
GET /_snapshot/backup-repo/snapshot-2026.08.25
恢复索引:
POST /_snapshot/backup-repo/snapshot-2026.08.25/_restore?wait_for_completion=false
{
"indices": "orders-v3",
"rename_pattern": "(.+)",
"rename_replacement": "restored-$1",
"index_settings": {
"index.number_of_replicas": 1
}
}
查看恢复进度:
GET /_recovery?human
GET /_cat/recovery/restored-orders-v3?v
取消恢复:
POST /orders-v3/_close
POST /_snapshot/backup-repo/snapshot-2026.08.25/_cancel
实际取消方式与当前恢复任务相关,生产应在 Runbook 中写清版本适用的命令。恢复演练要验证:
- 恢复后的索引 Mapping 正确;
- 文档数和关键指标一致;
- 别名切换流程可执行;
- 应用能正常读写;
- 恢复时间满足 RTO。
32.6 Searchable Snapshot
Searchable Snapshot 允许把快照中的数据直接作为可搜索分片挂载,适合 cold/frozen 层。
POST /_snapshot/backup-repo/snapshot-2026.08.25/_mount?storage=full_copy
{
"index": "logs-app-2026.08.01",
"renamed_index": "mounted-logs-2026.08.01",
"index_settings": {
"index.number_of_replicas": 0
}
}
价值:
- 降低本地存储成本;
- 快照数据可查询;
- 适合冷日志和审计数据。
限制:
- 查询延迟通常高于本地 hot 数据;
- 依赖对象存储性能;
- 不适合高频交互查询;
- 配置与版本能力相关;
- 权限和仓库治理仍然必要。
32.7 跨机房与异地容灾
常见模式:
| 模式 | 做法 | 适合 |
|---|---|---|
| 主备集群 | 主集群快照到远端,备集群恢复 | RPO/RTO 中等 |
| 双活写入 | 应用双写或消息广播 | 一致性复杂 |
| 远程查询 | CCS 查询远端集群 | 联合查询 |
| 数据重建 | 从 MySQL/Kafka 重建索引 | 搜索和分析场景 |
| 云多区 | 同城多可用区部署 | 网络延迟低 |
同城多可用区通常优先于跨城双活。跨城集群会受网络延迟影响,写入和选主都可能变差。
搜索类系统更常用:
MySQL / Kafka 作为事实来源
-> 同步服务
-> ES 主集群
-> 快照远端
-> 灾备集群可重建
灾备不只是数据恢复,还包括:
- 配置版本管理;
- 索引模板;
- ILM;
- 用户和角色;
- 别名;
- 监控和告警;
- DNS 或网关切换;
- 应用降级逻辑。
32.8 容量规划
容量估算至少考虑:
原始数据量
x 副本数
x 索引结构放大系数
x 预留水位
+ 峰值 merge 临时空间
+ 恢复临时空间
示例:
原始数据 10TB
副本数 1
结构放大估算 1.2
可用水位 70%
所需磁盘 = 10 * 2 * 1.2 / 0.7 = 34.3TB
这不是精确值,必须通过真实数据压测校准。还要评估:
- 写入 docs/s;
- 查询 QPS;
- P95/P99 延迟;
- CPU 使用率;
- JVM heap;
- 页缓存命中率;
- 磁盘 IOPS 和吞吐;
- 网络流量;
- 分片数量和大小。
32.9 扩缩容
扩容步骤:
- 明确瓶颈:磁盘、CPU、页缓存、查询扇出;
- 新节点使用相同或兼容配置;
- 低峰加入集群;
- 控制恢复和 rebalance 速度;
- 观察分片均衡;
- 验证查询和写入延迟;
- 更新容量报告。
限制迁移速度:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.cluster_concurrent_rebalance": "2",
"indices.recovery.max_bytes_per_sec": "100mb"
}
}
缩容必须先确认:
- 节点上没有唯一主分片;
- 数据可以迁移; -磁盘余量足够;
- 查询峰值不会马上到来;
- 有回滚路径。
使用 allocation filter 驱逐分片:
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.exclude._name": "es-data-old-01"
}
}
迁移完成后移除节点,再清理过滤规则。
32.10 滚动升级
升级前:
- 阅读官方升级路径和 breaking changes;
- 备份配置和快照;
- 在测试环境演练;
- 确认插件和客户端兼容;
- 停止索引自动分配;
- 通知写入方准备重试。
滚动流程:
禁用新分片分配
-> 关闭非关键索引(可选)
-> 停止一个节点
-> 升级该节点
-> 启动并重新加入
-> 等待集群稳定
-> 重复
-> 恢复分片分配
-> 升级 Kibana / 客户端
核心原则:
- 一次只处理一个节点;
- 不让 master quorum 同时下线;
- 跨大版本先做快照和兼容测试;
- 客户端与应用同步升级;
- 每一步都有健康检查和回退点。
32.11 故障演练
至少定期演练:
| 演练 | 验证 |
|---|---|
| 单 data 节点宕机 | 副本可用、写入可恢复 |
| master 节点宕机 | 选主时间、集群可用 |
| 磁盘水位 | 告警和写入保护 |
| 快照恢复 | RTO、RPO、数据完整性 |
| Kafka 积压 | 写入背压和恢复 |
| 慢查询 | 限流、取消、降级 |
| 网络分区 | quorum 和可用性 |
| 误删索引 | 恢复流程和审批 |
演练要有观测指标:
- 集群变为 yellow/red 的时间;
- 告警触发时间;
- 写入失败量;
- 查询错误率;
- 恢复耗时;
- 业务侧降级是否生效。
32.12 高可用检查清单
- master quorum 至少 3 节点;
- 副本分布跨节点和故障域;
- 磁盘余量充足;
- 快照每日成功并异地保存;
- 快照恢复定期演练;
- ILM 自动管理保留;
- 滚动升级方案可回退;
- 缩容前有分片迁移验证;
- Kafka 或队列有缓冲能力;
- 应用有搜索降级;
- 监控告警和 Runbook 完整;
- 容量报告每周更新。
本章小结
高可用由冗余、隔离、备份、可恢复和可演练共同组成。副本解决节点级故障,awareness 解决故障域问题,快照解决逻辑损坏和机房级故障,容量治理避免系统在增长中被动触顶。能被演练验证过的方案,才是真正的高可用方案。
思考题
- 副本和快照分别解决什么故障?
- RPO 和 RTO 如何影响架构选择?
- 为什么同城多可用区常优于跨城双活?
- 扩容前如何确认应该加节点还是重建索引分片数?
- 滚动升级时为什么要控制 quorum 和 allocation?