ElasticsearchNotes

第 32 章:高可用与容量治理

zjc 于 2026-02-01 发布

这是《Elasticsearch 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 高可用不是“副本数设置为 2”这么简单。它包含节点冗余、分片分布、机架感知、快照备份、跨机房容灾、容量规划、滚动升级和故障演练。容量治理则回答:现在够不够、多久会不够、扩容后是否仍然安全。

32.1 可用性目标

先定义业务目标:

场景 RPO RTO 建议架构
商品搜索 分钟级同步 5-15 分钟 多节点、可重建索引
日志检索 可容忍队列缓冲 15-30 分钟 Kafka 削峰、多节点
订单分析 分钟级 30 分钟 主数据源可重建
安全审计 近零丢失 依合规要求 独立集群、快照、远程备份

关键概念:

如果搜索索引可以从主数据源重建,架构会比把 ES 当最终数据库更从容。

32.2 节点与分片冗余

基本要求:

机架感知:

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

关键字段:

适合网络抖动或计划内短暂重启。如果节点确定不会恢复,应手动触发分配或扩容,而不是无限等待。

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 中写清版本适用的命令。恢复演练要验证:

  1. 恢复后的索引 Mapping 正确;
  2. 文档数和关键指标一致;
  3. 别名切换流程可执行;
  4. 应用能正常读写;
  5. 恢复时间满足 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
  }
}

价值:

限制:

32.7 跨机房与异地容灾

常见模式:

模式 做法 适合
主备集群 主集群快照到远端,备集群恢复 RPO/RTO 中等
双活写入 应用双写或消息广播 一致性复杂
远程查询 CCS 查询远端集群 联合查询
数据重建 从 MySQL/Kafka 重建索引 搜索和分析场景
云多区 同城多可用区部署 网络延迟低

同城多可用区通常优先于跨城双活。跨城集群会受网络延迟影响,写入和选主都可能变差。

搜索类系统更常用:

MySQL / Kafka 作为事实来源
  -> 同步服务
  -> ES 主集群
  -> 快照远端
  -> 灾备集群可重建

灾备不只是数据恢复,还包括:

32.8 容量规划

容量估算至少考虑:

原始数据量
  x 副本数
  x 索引结构放大系数
  x 预留水位
  + 峰值 merge 临时空间
  + 恢复临时空间

示例:

原始数据 10TB
副本数 1
结构放大估算 1.2
可用水位 70%

所需磁盘 = 10 * 2 * 1.2 / 0.7 = 34.3TB

这不是精确值,必须通过真实数据压测校准。还要评估:

32.9 扩缩容

扩容步骤:

  1. 明确瓶颈:磁盘、CPU、页缓存、查询扇出;
  2. 新节点使用相同或兼容配置;
  3. 低峰加入集群;
  4. 控制恢复和 rebalance 速度;
  5. 观察分片均衡;
  6. 验证查询和写入延迟;
  7. 更新容量报告。

限制迁移速度:

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 滚动升级

升级前:

滚动流程:

禁用新分片分配
  -> 关闭非关键索引(可选)
  -> 停止一个节点
  -> 升级该节点
  -> 启动并重新加入
  -> 等待集群稳定
  -> 重复
  -> 恢复分片分配
  -> 升级 Kibana / 客户端

核心原则:

32.11 故障演练

至少定期演练:

演练 验证
单 data 节点宕机 副本可用、写入可恢复
master 节点宕机 选主时间、集群可用
磁盘水位 告警和写入保护
快照恢复 RTO、RPO、数据完整性
Kafka 积压 写入背压和恢复
慢查询 限流、取消、降级
网络分区 quorum 和可用性
误删索引 恢复流程和审批

演练要有观测指标:

32.12 高可用检查清单

本章小结

高可用由冗余、隔离、备份、可恢复和可演练共同组成。副本解决节点级故障,awareness 解决故障域问题,快照解决逻辑损坏和机房级故障,容量治理避免系统在增长中被动触顶。能被演练验证过的方案,才是真正的高可用方案。

思考题

  1. 副本和快照分别解决什么故障?
  2. RPO 和 RTO 如何影响架构选择?
  3. 为什么同城多可用区常优于跨城双活?
  4. 扩容前如何确认应该加节点还是重建索引分片数?
  5. 滚动升级时为什么要控制 quorum 和 allocation?