mcpField
E
elasticsearch-cluster-health

elasticsearch-cluster-health

github.com/elastic云与 DevOps6021.1k 次安装今天更新
代码仓库

关于 elasticsearch-cluster-health

面向 Elasticsearch 运维人员的只读集群诊断技能。它通过 `elastic` CLI 定位受影响的索引、判断分配阻断原因并给出修复建议,不更改集群状态。

主要功能

  1. 01只读检查集群健康状态
  2. 02优先定位一个受影响索引
  3. 03分类判断分配决策器
  4. 04区分副本缺失与主分片缺失
  5. 05报告原因和修复建议

适用场景

  1. 01排查副本未分配的黄色集群
  2. 02调查主分片未分配的红色集群
  3. 03检查分片恢复是否正在推进

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elastic/agent-skills --skill elasticsearch-cluster-health

安装后在 Claude Code 中输入/elasticsearch-cluster-health确认已加载。

详细介绍

诊断集群健康状况

以只读方式对状态非绿色的 Elasticsearch 集群进行分诊:定位问题、判断分配决策器类别,并报告最可能的单一原因及补救措施。绝不修改集群状态——只呈现调查结果,由操作员采取行动。

环境配置

此技能通过 elastic CLI 执行 Elasticsearch 操作。如果未安装 elastic CLI,请告知用户需要安装它。 不要猜测凭据、直接调用 HTTP API,也不要尝试其他变通方法。

此技能以 HTTP 简写形式引用操作(例如,GET /、GET /_cat/indices、GET /{index}/_mapping、 GET /{index}/_settings/index.mode、POST /_query)。本文末尾的 操作 表格 将每个简写对应到等效的 elastic CLI 命令——始终使用 CLI,而不是直接调用 HTTP API。

流程

  1. 读取整体状态。 调用 GET /_cluster/health。status 字段给出判定结果:

    • green — 所有主分片和副本分片均已分配。报告集群健康,然后停止。
    • yellow — 所有主分片均已分配,但至少有一个副本分片未分配。数据仍可读取;冗余能力已降低。这不代表数据丢失。
    • red — 至少有一个主分片未分配。该分片的数据不可用;应视为紧急情况。

    同时读取 unassigned_shards、initializing_shards 和 relocating_shards。判定规则:仅当 状态为 yellow 或 red 时才继续。如果 initializing_shards > 0 且 unassigned_shards == 0,集群正在自行恢复——调用 GET /_cat/recovery 确认进度,等待后重新检查 GET /_cluster/health,再决定是否升级处理。

    所需数据:集群范围的 status 和分片计数。

  2. 将问题定位到一个索引。 调用 GET /_cluster/health?level=indices,找出导致集群整体状态的 索引:

    • 任何红色索引的优先级都高于所有黄色索引。
    • 在红色或黄色索引中,优先选择 unassigned_shards 数量最多的索引。
    • 红色系统索引(.security、.kibana*、.fleet-*)的优先级高于应用索引,因为其余 技术栈依赖这些索引。

    可以选择调用 GET /_cat/shards/{index}?h=index,shard,prirep,state,unassigned.reason,列出该索引上的所有未分配 分片,并查看故障分片是主分片(prirep=p)还是副本分片(prirep=r)。

    判定规则:后续步骤只关注一个索引——恢复该索引即可解除集群受阻状态。

    所需数据:各索引的 status 和 unassigned_shards;如有,则包括分片角色(主分片或副本分片)。

  3. 区分触发因素与根本原因。 不带请求正文调用 POST /_cluster/allocation/explain,由 Elasticsearch 选择 一个未分配分片;或者明确指定最严重的分片:

    { "index": "<index>", "shard": <id>, "primary": <true|false> }
    

    按以下顺序读取这些字段:

    • primary — false 表示未分配的是副本分片(通常为黄色);true 表示未分配的是主分片 (通常为红色)。
    • can_allocate — 顶层分配判定结果(no、yes、throttled、no_valid_shard_copy 等)。
    • unassigned_info.reason — 触发重新分配的原因(例如,NODE_LEFT、INDEX_CREATED)。当 can_allocate 为 no 时,这不是 根本原因;它只说明分片为何变为未分配状态。
    • allocate_explanation — 人类可读的摘要;在报告中逐字引用。
    • node_allocation_decisions[].deciders[] — 各节点的决策器结果。找出 decision: "NO" 的决策器;决策器名称 (例如,disk_threshold、filter、awareness)就是根本原因类别。 判定:
    • 黄色 + primary: false——影响仅限副本冗余;不会丢失数据。继续执行第 4 步,找出阻塞决策器(不要在 NODE_LEFT 处停止)。
    • 红色 + primary: true——该分片的数据缺失。继续执行第 4 步;如果 can_allocate 为 no_valid_shard_copy,则立即视为可能发生了数据丢失。

    所需数据:所选索引中一个具有代表性的未分配分片的 allocation-explain 响应。

  4. 对决策器分类。 将阻塞信号映射到原因类别。优先选择 decision: "NO" 的决策器,而不是 unassigned_info.reason 触发原因。

    信号原因类别典型修复措施(由运维人员执行)
    decider: disk_threshold,decision: NO超出磁盘高/低水位线释放指定节点上的磁盘空间、增加数据节点容量,或在通过 GET /_cat/allocation 确认使用情况后调整 cluster.routing.allocation.disk.watermark.*
    decider: filter 或 decider: awareness,decision: NO分配筛选或区域感知添加符合 index.routing.allocation.* / 感知属性要求的节点,或调整索引/集群分配设置
    decider: throttling 或正在进行恢复临时恢复等待;监控 GET /_cat/recovery 并重新检查 GET /_cluster/health
    can_allocate: no_valid_shard_copy(通常伴有空的 node_allocation_decisions)没有可用的分片副本参见第 5 步——数据丢失场景
    can_allocate: yes,但分片仍未分配延迟分配或集群状态追赶检查 unassigned_info.at 中的延迟时间;等待后重新检查

    对于磁盘压力(NODE_LEFT 后常见的黄色状态):副本会迁移到其余节点;如果某个存活节点超过高水位线(cluster.routing.allocation.disk.watermark.high,默认值为 90%),即使主分片仍已分配,disk_threshold 决策器也会阻止副本分配。解决方法是增加磁盘容量或缓解水位线压力——不要删除索引或强制分配空主分片。

    所需数据:决策器名称、explanation 文本,以及 node_allocation_decisions 中受影响的节点名称。

  5. 建议修复措施——只读分诊到此结束。 报告最可能的单一原因(决策器类别 + 原文照录的 allocate_explanation)以及一条主要修复路径。根据颜色和分片角色匹配紧急程度。 黄色 / 副本未分配(无数据丢失):

    • 明确说明:所有主分片均已分配;仅副本缺失;无数据丢失。
    • 指出真正的决策因素(例如 es-node-2 上的磁盘高水位),而不只是说“某个节点离开了”。
    • 建议:释放磁盘空间、扩展存储、添加数据节点,或在检查 GET /_cat/allocation 后调整磁盘水位线。
    • 不要建议:删除索引、使用 allocate_empty_primary、强制在正常主分片上分配,或在没有证据的情况下 重启整个集群。

    红色 / 主分片未分配,且原因是 no_valid_shard_copy(有数据丢失风险):

    • 明确说明:有一个主分片未分配;该分片的查询/路由会失败;应将其视为紧急问题,且范围仅限于指定索引。
    • 解释:唯一的副本位于已离开的节点上;由于其他剩余节点上都没有有效副本,Elasticsearch 无法分配主分片 (can_allocate: no_valid_shard_copy)。
    • 按以下顺序说明恢复路径:
      1. 如果已离开节点的数据目录完好,则将该节点恢复上线——分片副本会随之恢复。
      2. 从快照恢复到该索引(或恢复到新索引后再重新索引),前提是存在快照。
      3. **仅作为最后手段:**使用 POST /_cluster/reroute 和 allocate_empty_primary——这会创建一个空主分片, 并永久丢失该分片上的所有文档。必须明确说明数据丢失;绝不能将其作为首选或随意采用的修复方法。
    • 不要建议:不讨论数据丢失就删除索引,或不附带数据丢失警告就使用 allocate_empty_primary。

    自愈正在进行:

    • 当决策因素显示存在限流或正在进行对等恢复时,建议等待,并重新检查上述只读 API。

    不要执行重新路由、快照恢复或设置更改——只说明原因和修复建议。

指南

  • **只读:**仅使用 GET/POST explain API 进行问题诊断。修复措施仅作为建议;由运维人员执行写入操作。
  • 触发因素 ≠ 原因:unassigned_info.reason: NODE_LEFT 解释了事件;node_allocation_decisions 中的决策因素 则解释了分配仍然失败的原因。
  • **副本与主分片:**黄色状态 + primary: false = 冗余不足,并非数据丢失。红色状态 + primary: true = 该分片的数据缺失。
  • **一个索引,一个原因:**选择影响最大的索引和最关键的 NO 决策因素;避免列出每个分片。
  • **Cat 辅助 API:**当决策因素类别不明确或恢复正在进行时,使用 GET /_cat/allocation 查看每个节点的磁盘 使用率,并使用 GET /_cat/recovery 查看正在进行的恢复。

示例

黄色——节点离开后触发磁盘水位线。 集群健康状态显示 logs-2025-07 上有未分配副本,因此状态为黄色。 分配解释返回 primary: false、unassigned_info.reason: NODE_LEFT,但 es-node-2 上的 disk_threshold 决策因素为 NO (“超过高水位……90%”)。报告:无数据丢失;根本原因是接收节点的磁盘空间紧张;应处理磁盘空间/水位线问题,而不只是说“节点离开了”。

红色——主分片没有有效副本。 集群健康状态显示 orders-2025 为红色,且有一个分片未分配。解释结果返回 primary: true、can_allocate: no_valid_shard_copy、last_allocation_status: no_valid_shard_copy。报告:问题紧急; 主分片数据缺失;恢复节点或从快照恢复;仅将 allocate_empty_primary 作为最后手段提及,并明确说明数据会丢失。

Operations

HTTP API (shorthand)elastic CLI command
GET /_cluster/healthelastic es cluster health
GET /_cluster/health?level=indiceselastic es cluster health --level indices
POST /_cluster/allocation/explainelastic es cluster allocation-explain
POST /_cluster/allocation/explain (specific shard)elastic es cluster allocation-explain --index '<index>' --shard <id> --primary true (replica: false)
GET /_cat/allocationelastic es cat allocation
GET /_cat/recoveryelastic es cat recovery
GET /_cat/shards/{index}?h=index,shard,prirep,state,unassigned.reasonelastic es cat shards --index '<index>' --h index,shard,prirep,state,unassigned.reason
POST /_cluster/reroute (last-resort empty primary — operator only)elastic es cluster reroute --commands '<json>'

评论

支持 Markdown