Elasticsearch 8.x 故障应急 Runbook

3 阅读19分钟

适用版本:Elasticsearch 8.6+ 适用范围:生产、预生产集群 文档定位:On-Call 值班在故障发生时的逐步操作手册。每个场景从"接到告警"到"恢复确认"全流程可执行 配套文档:《Elasticsearch 部署与运维手册》、《监控告警手册》


使用指南

阅读约定

每个场景按统一模板:

§N. 场景名称
─────────────
触发:       什么告警/现象触发本 runbook
P 级:       默认 P 级(可根据实际影响升降级)
平均处置时间: MTTR 参考值
影响:       业务侧表现
止血优先:   先做什么恢复服务
诊断步骤:   逐条命令 + 预期输出
根因分类:   常见原因
处置动作:   按根因分别给出操作
恢复确认:   如何验证已恢复
事后行动:   需要补充的复盘项
升级条件:   什么情况升级到上级

操作纪律

  1. 任何破坏性操作(DELETE / 强制分配 / voting 排除)必须双人在场
  2. 执行前先 ack 告警,避免重复响应
  3. 每步操作记录到故障 IM 频道(时间 + 命令 + 输出关键字段)
  4. 不确定时 → 升级,不硬撑
  5. 故障期间禁止做"顺手优化",单一变更原则

场景索引

§场景触发告警P 级
1集群 RedESClusterRedP0
2集群 Yellow 持续ESClusterYellowProlongedP1
3Master 节点宕机 / 失主ESNodeDown (master)P1
4Data 节点宕机ESNodeDown (data)P2
5磁盘水位告警ESDiskHighP1/P2
6JVM Heap 高 / Old GC 频繁ESHeapHighP1
7写入被拒绝(bulk_rejected)ESBulkRejectedP2
8查询慢 / 查询被拒绝ESSearchRejected / ESQueryLatencyHighP2
9备份失败 / 快照缺失ESSnapshotFailedP1/P2
10证书即将过期ESCertExpiringP1/P3
11误删索引 / 数据人工告警P0
12脑裂 / 分裂集群人工告警P0
13负载不均 / 单节点热点人工告警P3
14Reindex / 大任务卡住人工告警P2
15Circuit Breaker 触发ESCircuitBreakerTrippedP2

1. 集群 Red

触发ESClusterRed(cluster_status = red) P 级:P0 平均处置时间:30 分钟 ~ 数小时 影响:至少一个 primary shard 不可用,对应索引部分文档无法读写

1.1 止血优先

如果是某个非关键索引导致 red,先确认是否可以临时关闭该索引让集群快速回 green:

# 找出 red 的索引
GET /_cluster/health?level=indices | jq '.indices | to_entries[] | select(.value.status=="red") | .key'

# 评估可关闭性(业务方确认)后:
POST /<red-index>/_close

关闭后集群 status 立即回升,但只是暂时止血,必须继续处置。

1.2 诊断步骤

# 步骤 1: 整体健康
GET /_cluster/health?pretty
# 关注: unassigned_shards, number_of_nodes

# 步骤 2: 找出 red 索引和具体 unassigned shard
GET /_cluster/health?level=shards | jq '.indices | to_entries[] | select(.value.status=="red")'

# 步骤 3: 查询未分配原因(最关键)
GET /_cluster/allocation/explain
{
  "index": "<red-index>",
  "shard": 0,
  "primary": true
}
# 关注 allocate_explanation 和 node_allocation_decisions

1.3 根因分类与处置

A. 节点宕机导致 primary 丢失

特征allocation_explain 返回 no_valid_shard_copy

处置

  1. 检查宕机节点是否可恢复(机器层面)
  2. 若节点可拉起 → 按 §4 处置
  3. 若节点磁盘损坏不可恢复且无其他副本
    • 检查最近一次快照
    • 评估业务影响后,从快照恢复(数据回退到快照点)
    • 或接受数据丢失,强制分配空 shard:
# 危险操作 — 接受数据丢失
POST /_cluster/reroute?retry_failed=true
{
  "commands": [{
    "allocate_empty_primary": {
      "index": "<idx>",
      "shard": 0,
      "node": "<healthy-node>",
      "accept_data_loss": true
    }
  }]
}

此操作 L4 级别,必须 CTO 授权

B. 磁盘水位超 95%(flood_stage)

特征allocation_explain 返回 disk_threshold 拒绝

处置:见 §5

C. 副本数 > (节点数 - 1)

特征allocation_explain 提示无可用节点(同分片不能在同节点)

处置:减小副本数

PUT /<idx>/_settings { "index.number_of_replicas": 1 }

D. shard allocation awareness 配置错误

特征allocation_explain 提示 zone 限制

处置:检查 cluster.routing.allocation.awareness.* 与节点 node.attr.zone 是否匹配

1.4 恢复确认

GET /_cluster/health
# status = green
# unassigned_shards = 0
# initializing_shards = 0

业务方验证:抽样查询关键索引文档可读。

1.5 事后行动

  • 复盘文档(24h 内)
  • 确认所有索引副本数 ≥ 1
  • 检查快照覆盖度
  • 评估是否需要增加 awareness 维度

1.6 升级条件

  • 数据丢失风险 → 立即通知 CTO
  • 30 分钟未止血 → 升级架构组
  • 涉及核心业务索引 → 业务团队同步

2. 集群 Yellow 持续

触发ESClusterYellowProlonged(yellow > 30min) P 级:P1 MTTR:15 分钟 ~ 2 小时 影响:有副本 shard 未分配,单节点故障即转 red

2.1 诊断步骤

GET /_cluster/health?level=indices | jq '.indices | to_entries[] | select(.value.status=="yellow")'

# 找具体 shard 和原因
GET /_cluster/allocation/explain

2.2 根因与处置

A. 单节点集群配置了 replica

特征:节点数 = 1,但索引 number_of_replicas ≥ 1

处置:扩节点 或 临时改为 0(不推荐生产)

B. 新加入节点未完成 recovery

特征initializing_shards > 0,给点时间会自动恢复

处置:等待,加大恢复速度(谨慎):

PUT /_cluster/settings
{
  "transient": {
    "indices.recovery.max_bytes_per_sec": "200mb",
    "cluster.routing.allocation.node_concurrent_recoveries": 4
  }
}

C. 节点磁盘 high watermark(85%)

特征:副本无法分配到该节点

处置:见 §5

D. allocation 被禁用

特征cluster.routing.allocation.enable 不是 all

GET /_cluster/settings
PUT /_cluster/settings
{ "persistent": { "cluster.routing.allocation.enable": null } }

滚动重启遗忘恢复 enable 是常见原因。

2.3 恢复确认

status = green,且 unassigned_shards = 0

2.4 升级条件

  • 持续 2 小时未恢复 → SRE Lead

3. Master 节点宕机 / 失主

触发ESNodeDown 且节点角色含 master P 级:P1 MTTR:5 ~ 30 分钟 影响:新选主期间,集群短暂只读、状态变更阻塞

3.1 立即确认

# 当前 master
GET /_cat/master?v

# master 候选数
GET /_cat/nodes?v | grep '\*\|m'

前置假设:3 个 master 候选,宕 1 不影响多数派;宕 2 立即 P0 升级。

3.2 处置步骤

单 master 宕机

  1. 集群通常会在 30s 内自动选出新 master
  2. 检查宕机节点:
    • 机器层:是否可远程登录、是否系统级故障
    • ES 层:进程是否 OOM、磁盘是否满、配置是否被改
  3. 修复后正常拉起:
systemctl start elasticsearch
journalctl -u elasticsearch -f
  1. 等待节点 join:
GET /_cat/nodes?v
  1. 完成

多 master 同时宕机(多数派不可用)

P0 紧急情况

  1. 不要慌乱启停其他 master
  2. 不要修改 cluster.initial_master_nodes
  3. 优先恢复任一宕机 master:
    • 修复机器
    • 启动 ES
  4. 一旦多数派恢复,集群自动恢复
  5. 仍无法恢复 → CTO 授权 → 走"unsafe bootstrap"流程(需要 Elastic 官方文档指引,禁止自行尝试)

3.3 恢复确认

GET /_cluster/health
# number_of_nodes 与预期一致
# status >= yellow

3.4 升级条件

  • 多数派 master 不可用 → P0 + 立即升级 CTO + 联系 Elastic Support

4. Data 节点宕机

触发ESNodeDown 且节点角色含 data P 级:P2(导致 yellow)/ P1(导致 red) MTTR:5 ~ 30 分钟 影响:节点上 primary shard 短暂不可用,副本接管

4.1 诊断

# 确认宕机节点
GET /_cat/nodes?v

# 该节点上的分片状态
GET /_cat/shards?v | grep <down-node-name>
# 应该看到 UNASSIGNED 或 INITIALIZING

4.2 处置

节点可快速恢复(< 5min)

  1. 修复并启动节点
  2. 等待自动 recover
  3. ES 默认 1 分钟内的恢复使用本地数据,避免重新拷贝

节点恢复较慢(> 5min)

ES 会开始向其他节点复制副本,可能引发 IO 压力。

临时延迟自动恢复(已知节点很快回来):

PUT /_all/_settings
{
  "settings": {
    "index.unassigned.node_left.delayed_timeout": "10m"
  }
}

⚠ 仅在明确节点会回来时使用。

节点彻底报废

# 1. 从集群排空(其实节点已经下线,这一步是确认 ES 不再等它)
PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.exclude._name": "<dead-node>"
  }
}

# 2. 等待分片重新均衡
GET /_cluster/health
# unassigned_shards 持续下降

# 3. 准备替换节点(按部署手册 §8)
# 4. 替换节点上线后清除 exclude
PUT /_cluster/settings
{ "transient": { "cluster.routing.allocation.exclude._name": null } }

4.3 恢复确认

unassigned_shards = 0,集群 green

4.4 升级条件

  • 同时多个 data 节点宕机 → 接近多数派副本丢失 → P0
  • 4 小时未恢复 → SRE Lead

5. 磁盘水位告警

触发ESDiskHigh(>80%)/ ESDiskWarning(>70%) P 级:P1(>80%)/ P2(>70%) MTTR:30 分钟 ~ 数小时 影响:85% low watermark 后无新分片分配;90% high 后副本迁移;95% flood_stage 后所有索引强制只读

5.1 立即确认

GET /_cat/allocation?v&s=disk.used_percent:desc

定位高水位节点和具体磁盘。

5.2 紧急止血(接近 95% flood_stage)

优先级排序

  1. 删除已知废弃索引
GET /_cat/indices?v&s=store.size:desc | head -50
# 与业务方确认后
DELETE /<obsolete-index>
  1. 下线已过期的 ILM 阶段
GET /_ilm/explain
# 找出已过期但未删除的索引,手工删除
  1. 关闭非必要索引(释放部分内存与文件句柄,但磁盘不会释放):
POST /<idx>/_close
  1. 临时调高 flood_stage(仅紧急救场,30 分钟内必须恢复):
PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.flood_stage": "97%",
    "cluster.routing.allocation.disk.watermark.flood_stage.frozen": "99%"
  }
}

⚠ 此举仅延迟问题,不解决问题。

  1. 解除已只读的索引(清完磁盘后):
PUT /_all/_settings
{ "index.blocks.read_only_allow_delete": null }

5.3 根本处置

A. 数据增长超出容量规划

→ 扩容(按部署手册 §10)

B. ILM 策略不工作

GET /_ilm/explain | jq '.indices | to_entries[] | select(.value.step=="ERROR")'

排查并修复 ILM 错误。

C. 单节点磁盘倾斜

→ 见 §13 负载不均

5.4 恢复确认

GET /_cat/allocation?v
# disk.used_percent 全部 < 70%
GET /_cluster/health
# status = green

5.5 升级条件

  • 已触发 flood_stage 且 30min 内无法恢复 → P0 + 升级架构组
  • 多节点接近 90% → 紧急扩容

6. JVM Heap 高 / Old GC 频繁

触发ESHeapHigh(>85% 持续 10min)/ ESOldGCFrequent P 级:P1 MTTR:1 ~ 4 小时(多数需重启或长期治理) 影响:响应延迟上升、可能 OOM

6.1 诊断步骤

# 各节点 heap
GET /_cat/nodes?v&h=name,heap.percent,heap.current,heap.max,jvm.mem.young_used,jvm.mem.old_used

# Heap 占用分类(关键)
GET /_nodes/stats/breaker,fielddata,query_cache,request_cache,segments?human

# 当前在跑的查询
GET /_tasks?actions=*search*&detailed

6.2 根因排查

A. 单查询打爆 heap

特征circuit_breaker_tripped 同时出现,请求被拒绝

处置

  1. 找出大查询:
GET /_tasks?actions=*search*&detailed | jq '[.nodes[].tasks[]] | sort_by(-.running_time_in_nanos) | .[0:5]'
  1. 取消:
POST /_tasks/<task_id>/_cancel
  1. 找责任方修代码(见 §8)

B. fielddata 占用过高

特征fielddata.memory_size 占 heap > 30%

处置:清缓存(治标):

POST /_cache/clear?fielddata=true

根治:检查是否有 text 字段被聚合/排序,改为 keyword(《开发规范》§4)

C. segments 过多

特征segments.count 持续上升,segments.memory_in_bytes

处置:force merge(仅在写入空闲索引):

POST /<old-idx>/_forcemerge?max_num_segments=1&wait_for_completion=false

D. 分片过多

特征:单节点 shards 数 / heap GB > 20

处置:合并/删除小索引;启用 ILM 的 shrink + delete

E. 内存泄漏 / 真实 OOM

特征:节点重启后短期再次升高

处置

  1. 抓 heap dump:
jmap -dump:format=b,file=/tmp/heap.bin <pid>
  1. 上传到分析平台(MAT/Eclipse Memory Analyzer)
  2. 联系 Elastic Support 协助分析
  3. 临时缓解:滚动重启

6.3 恢复确认

  • 全部节点 heap < 75%
  • Old GC 时间占比 < 5%
  • 业务查询 P99 回到基线

6.4 升级条件

  • 节点真实 OOM 重启 → P0
  • 多节点同时 > 90% → P0

7. 写入被拒绝(bulk_rejected)

触发ESBulkRejected(write 线程池有 rejected) P 级:P2 MTTR:15 ~ 60 分钟 影响:客户端 429 错误,bulk 部分 item 被拒,可能导致数据丢失

7.1 诊断步骤

# 哪些节点在拒
GET /_cat/thread_pool?v&h=node_name,name,active,queue,rejected | grep write

# 当前写入压力
GET /_nodes/stats/indices/indexing | jq '.nodes | to_entries[] | {node:.value.name, ops:.value.indices.indexing.index_total, time:.value.indices.indexing.index_time_in_millis}'

7.2 根因与处置

A. 客户端突发流量

特征:突然 QPS 上升数倍

处置

  1. 客户端侧:指数退避重试(429 是可重试状态)
  2. 应用侧:bulk batch size 调小到 < 5MB
  3. MQ 侧:消费者降速

B. Refresh 太频繁

特征refresh.total_time_in_millis 增速大

处置

PUT /<hot-idx>/_settings
{ "index.refresh_interval": "30s" }

写入完成后再调回。

C. Segment Merge 跟不上

特征merges.current 长期 > 5

处置

  • 临时增加 merge 线程:
# elasticsearch.yml — 需要重启生效
indices.merge.scheduler.max_thread_count: 4
  • 长期:磁盘 IO 升级到 NVMe;减少分片数

D. 单节点慢导致全集群拖累

特征:仅一两个节点 rejected,其他正常

处置

  1. 检查该节点磁盘 IO、CPU、网络
  2. 必要时下线节点(按 §10 部署手册)

7.3 恢复确认

  • rejected 增量 = 0 持续 5min
  • bulk 客户端无 429
  • 写入延迟回到基线

7.4 升级条件

  • 持续 1 小时未恢复 → SRE Lead
  • 业务核心数据丢失 → 立即升级

8. 查询慢 / 查询被拒绝

触发ESQueryLatencyHigh / ESSearchRejected P 级:P2 MTTR:30 分钟 ~ 数小时 影响:业务查询变慢/失败,下游 RT 上升

8.1 诊断步骤

# 当前在跑的查询(按耗时排序)
GET /_tasks?actions=*search*&detailed | jq '[.nodes[].tasks[]] | sort_by(-.running_time_in_nanos)'

# 慢查询日志
tail -f logs/<cluster>_index_search_slowlog.json

# 节点压力
GET /_cat/thread_pool?v&h=node_name,name,active,queue,rejected | grep search

8.2 紧急止血

取消正在跑的大查询

POST /_tasks/<task_id>/_cancel

客户端侧降级

通知业务方启用降级(见客户端 SDK 的 DegradationGate 章节),临时返回缓存或空结果。

8.3 根因排查

A. 突发慢查询(业务上线引入)

处置

  1. 慢查询日志取 X-Opaque-Id 关联应用 trace
  2. 通知业务方回滚或修复
  3. 业务侧禁用问题查询

B. 深分页

处置

  1. 慢查询日志中 from 字段较大
  2. 通知业务改为 search_after 或 PIT

C. 聚合无 size 限制

处置:临时通过 query 改写代理或要求业务修复

D. 缓存穿透

特征request_cache 命中率低

处置

  • 查询是否带 now(破坏缓存)→ 改为 now/h(小时粒度)
  • 业务侧加客户端缓存

E. 索引层 fielddata / 字段类型错误

→ 见 §6 fielddata 部分

8.4 恢复确认

  • 查询 P99 回到基线
  • 慢查询无新增
  • 业务关闭降级开关

8.5 升级条件

  • 业务侧无可降级方案 → 业务团队加入处置
  • 4 小时未恢复 → SRE Lead

9. 备份失败 / 快照缺失

触发ESSnapshotFailed / ESSnapshotMissing P 级:P1(缺失 > 36h)/ P2(单次失败) MTTR:30 分钟 ~ 4 小时 影响:故障恢复能力下降

9.1 诊断步骤

# SLM 状态
GET /_slm/policy
GET /_slm/stats

# 最近一次执行
GET /_slm/history?pretty

# 仓库连接性
GET /_snapshot/<repo-name>/_status
POST /_snapshot/<repo-name>/_verify

# 当前快照状态
GET /_cat/snapshots/<repo-name>?v&s=start_time:desc | head -10

9.2 根因与处置

A. S3/对象存储认证失败

处置

  • 检查 Vault 中 access key 是否过期
  • 重新注入 secrets,重启 ES(或仅 reload secure settings)
POST /_nodes/reload_secure_settings

B. 仓库容量满

处置

  • S3:检查 lifecycle 是否生效(旧快照清理)
  • 增加保留策略限制

C. SLM 策略禁用 / 误删

处置

  • GET /_slm/policy 确认存在
  • 重新创建(按部署手册 §12)

D. 网络问题

处置:从 ES 节点 telnet/curl 验证仓库连通

E. 单次快照执行中失败

处置:触发一次手工快照验证:

POST /_slm/policy/<policy-name>/_execute

9.3 恢复确认

  • _slm/stats.policy_stats 有近期成功记录
  • _cat/snapshots 有 SUCCESS 状态新快照

9.4 事后行动

  • 验证恢复演练(按部署手册 §12.4)

9.5 升级条件

  • 缺备份 > 72h → P1 + SRE Lead

10. 证书即将过期

触发ESCertExpiringSoon(30 天内)/ ESCertExpiringCritical(7 天内) P 级:P3 / P1 MTTR:4 小时(含滚动) 影响:过期后节点间通信中断、客户端无法连接

10.1 诊断

GET /_ssl/certificates?pretty
# 关注 expiry 字段

10.2 处置(提前 ≥ 30 天)

按部署手册 §7.1 流程:

  1. 用同一 CA 签发新节点证书
  2. 滚动重启更新证书(按 §11 部署手册)
  3. 验证:
GET /_ssl/certificates
# expiry 全部 > 1 年

10.3 紧急情况(< 7 天)

  1. 立即生效新证书的滚动重启窗口
  2. 同步业务方可能的客户端重启需求(若客户端校验服务端证书)
  3. 完成后审视为何监控未提前预警

10.4 升级条件

  • < 7 天未处理 → P1 + SRE Lead
  • < 24h → P0 + CTO

11. 误删索引 / 数据

触发:人工告警(业务反馈、运维误操作) P 级:P0 MTTR:30 分钟 ~ 数小时 影响:数据丢失,业务中断

11.1 立即动作(黄金 10 分钟)

1. 立即停止对应索引的所有写入(应用层、消费者)
2. 不要做任何 reindex / 重建操作
3. 不要重启 ES 节点
4. 通知 SRE Lead + 业务方 + 法务(如涉及合规)

11.2 评估损失

# 是否真的全删了
GET /_cat/indices?v | grep <index-name>

# 别名是否还在
GET /_cat/aliases?v | grep <index-name>

# 最近一次快照时间
GET /_cat/snapshots/<repo>?v&s=start_time:desc | head -5

11.3 恢复

A. 从快照恢复

POST /_snapshot/<repo>/<snapshot-id>/_restore
{
  "indices": "<deleted-index>",
  "rename_pattern":     "(.+)",
  "rename_replacement": "$1-restored",
  "include_global_state": false
}

恢复完成后:

POST /_aliases
{
  "actions": [
    { "add": { "index": "<deleted-index>-restored", "alias": "<biz-alias>" } }
  ]
}

B. 从上游补数据

如有 Kafka 等上游:

  1. 创建空索引(从模板)
  2. 上游 reset offset 到删除前的 timestamp
  3. 重新消费

⚠ 注意 Kafka 保留期,可能上游也已过期。

11.4 恢复确认

  • 别名指向新索引
  • 业务抽样查询正常
  • 文档数与删除前接近(接受少量差异)

11.5 事后行动(强制)

  • 复盘文档(48h 内,必须 CTO 签字)
  • 删索引权限收紧到 L4(双人 + CTO 授权)
  • 增加"删除前必快照"的工单 gate
  • 检查同类操作的所有路径

11.6 升级条件

  • 一旦确认误删 → 立即 P0 + CTO + 全员通知

12. 脑裂 / 分裂集群

触发:人工告警(监控发现两份 cluster_uuid、不同节点视图) P 级:P0 MTTR:1 ~ 8 小时 影响:数据分裂、双写、不可调和

12.1 现象

  • 不同节点 _cluster/state 显示不同 master
  • _cat/master 在不同节点查询结果不同
  • cluster_uuid 不一致

ES 7.x+ 引入 voting consensus 后脑裂极罕见,多发生于网络分区 + 配置错误。

12.2 处置

禁止自行尝试合并。立即:

  1. 止血:停止业务写入
  2. 升级:P0 + CTO + 联系 Elastic Support
  3. 隔离:断开少数派的 master 节点(不要拉起)
  4. 等待官方指导

12.3 后续

通常需要:

  • 选一份"权威集群"
  • 另一份的数据 reindex 到权威集群(按业务规则去重)
  • 重建少数派节点

12.4 预防

  • master 必须 3 节点跨 3 AZ
  • 严禁修改 cluster.initial_master_nodes
  • 网络监控:跨 AZ 延迟、丢包

13. 负载不均 / 单节点热点

触发:人工发现(个别节点 CPU/IO 持续高于其他节点) P 级:P3 MTTR:1 ~ 数小时 影响:少数节点拖累整体延迟

13.1 诊断

# 节点资源对比
GET /_cat/nodes?v&h=name,cpu,load_1m,heap.percent,disk.used_percent

# 节点分片数对比
GET /_cat/allocation?v&h=node,shards,disk.used,disk.used_percent

# 单索引分片分布
GET /_cat/shards/<hot-index>?v

13.2 根因

A. 分片分布不均

特征:节点分片数差异 > 20%

处置:触发再均衡

POST /_cluster/reroute?retry_failed=true&master_timeout=30s

或临时调整均衡敏感度(谨慎):

PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.balance.shard": 0.55
  }
}

B. 数据热点(routing 不均)

特征:自定义 routing 的索引中,某个 routing 值 doc 数远超其他

处置

  • 业务侧分散热点 key
  • 索引设计加 routing_partition_size(创建时设置,已存在索引无法改)

C. 查询热点(用户行为热点)

特征:某些 doc 被高频查询

处置

  • 增加 replica 数(读扩展)
  • 业务侧加缓存

13.3 升级条件

  • 分片分布严重偏斜(>50%)且无法均衡 → 架构组评估

14. Reindex / 大任务卡住

触发:人工告警(reindex 任务超过预期时间未完成、卡住) P 级:P2 MTTR:根据数据量 影响:占用集群资源、阻塞后续运维

14.1 诊断

# 查看任务进度
GET /_tasks?actions=*reindex*&detailed | jq

# 关注 status.created, status.updated, status.batches

14.2 处置

A. 限速过低

处置:调速

POST /_reindex/<task_id>/_rethrottle?requests_per_second=2000

B. 源/目标 mapping 不兼容(部分文档失败)

特征status.version_conflicts 或失败计数高

处置

  • 检查 mapping
  • 修正后重启任务(先 cancel)

C. 资源不足导致超时

处置

  • 停止:POST /_tasks/<task_id>/_cancel
  • 减小 batch size 重启
  • slices 分片:
POST /_reindex?slices=5&wait_for_completion=false

14.3 恢复确认

  • 任务完成或健康进行中
  • 集群其他指标正常

15. Circuit Breaker 触发

触发ESCircuitBreakerTripped P 级:P2 MTTR:15 ~ 60 分钟 影响:请求被拒绝,避免节点 OOM

15.1 诊断

GET /_nodes/stats/breaker?human
# 关注 estimated_size_in_bytes / limit_size_in_bytes
# tripped 计数有变化即触发过

常见 breaker:

breaker含义默认 limit
parent总和(最常见)95% heap
request单请求估算60% heap
fielddatafielddata 缓存40% heap
in_flight_requests在飞 HTTP 请求100% heap

15.2 处置

A. parent breaker(总和超限)

根因:heap 已逼近极限

处置:见 §6

B. request breaker

根因:单请求过大(多半是聚合)

处置

  • 找出问题查询并限制
  • 业务侧加 size 上限(聚合)
  • 客户端 SDK 启用 SearchHelper 校验

C. fielddata breaker

根因:text 字段被聚合

处置:见 §6 fielddata

15.3 不要做的事

禁止调高 breaker 限制以"绕过"问题——breaker 触发是保护,绕过 = 找 OOM。

15.4 恢复确认

  • 5 分钟无新 trip
  • 业务无 429 / circuit_breaker 错误

附录 A:常用诊断 cheat sheet

# === 集群级 ===
GET /_cluster/health
GET /_cluster/health?level=shards
GET /_cluster/allocation/explain
GET /_cluster/state/nodes,routing_table
GET /_cluster/pending_tasks
GET /_cat/pending_tasks?v

# === 节点级 ===
GET /_cat/nodes?v&h=name,node.role,heap.percent,ram.percent,cpu,load_1m,disk.used_percent
GET /_nodes/stats/jvm
GET /_nodes/stats/thread_pool
GET /_nodes/stats/breaker
GET /_nodes/hot_threads?threads=10

# === 索引级 ===
GET /_cat/indices?v&s=store.size:desc
GET /_cat/shards?v&s=store:desc
GET /_cat/recovery?v&active_only=true
GET /<idx>/_stats
GET /<idx>/_segments

# === 任务级 ===
GET /_tasks?detailed
GET /_tasks?actions=*search*&detailed
GET /_tasks?actions=*reindex*&detailed
POST /_tasks/<task_id>/_cancel

# === 缓存 ===
GET /_nodes/stats/indices/query_cache,request_cache,fielddata
POST /_cache/clear?fielddata=true

# === 快照 ===
GET /_cat/snapshots/<repo>?v
GET /_slm/policy
GET /_slm/stats
POST /_snapshot/<repo>/_verify

# === 安全 ===
GET /_ssl/certificates
GET /_security/api_key?owner=true

附录 B:故障复盘模板

每次 P0/P1 故障必须 24~48h 内出复盘文档,模板:

# 故障复盘:<标题>

- **故障级别**:P0/P1
- **故障时间**:YYYY-MM-DD HH:MM ~ HH:MM(共 X 分钟)
- **影响范围**:哪些业务、多少用户/请求、是否数据丢失
- **责任团队**:SRE / 业务

## 时间线(精确到分钟)

| 时间 | 事件 | 操作人 |
|------|------|--------|
| 10:00 | 告警触发 | - |
| 10:03 | On-Call ack | 张三 |
| 10:05 | 定位为...  | 张三 |
| 10:15 | 升级 SRE Lead | - |
| ...   | ... | ... |
| 11:30 | 业务恢复 | - |

## 直接原因

(导致故障的最近一步操作或事件)

## 根本原因(5 Why)

1. Why ...?
2. Why ...?
...

## 影响

- 业务影响:
- 数据影响:
- 客户影响:

## 处置过程评估

| 项 | 评分 | 说明 |
|----|------|------|
| 监控发现 | 1-5 | |
| 响应速度 | 1-5 | |
| 处置准确性 | 1-5 | |
| 沟通同步 | 1-5 | |
| 文档支撑 | 1-5 | |

## 改进项

| # | 改进项 | Owner | DDL | 验收标准 |
|---|--------|-------|-----|----------|
| 1 | ... | 张三 | 2026-05-25 | ... |
| 2 | ... | ... | ... | ... |

## 附件

- 关键日志片段
- 相关 PR / 工单
- 监控截图

文档版本

版本日期变更作者
v1.02026-05-11初版-

本 Runbook 为生产值班执行依据。每个新增故障场景必须补充到本文档。 季度演练后根据实际操作反馈更新。