关于 elasticsearch-cluster-health
面向 Elasticsearch 运维人员的只读集群诊断技能。它通过 `elastic` CLI 定位受影响的索引、判断分配阻断原因并给出修复建议,不更改集群状态。
主要功能
- 01只读检查集群健康状态
- 02优先定位一个受影响索引
- 03分类判断分配决策器
- 04区分副本缺失与主分片缺失
- 05报告原因和修复建议
适用场景
- 01排查副本未分配的黄色集群
- 02调查主分片未分配的红色集群
- 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。
流程
-
读取整体状态。 调用
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和分片计数。 -
将问题定位到一个索引。 调用
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;如有,则包括分片角色(主分片或副本分片)。 -
区分触发因素与根本原因。 不带请求正文调用
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 响应。
-
对决策器分类。 将阻塞信号映射到原因类别。优先选择
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/healthcan_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中受影响的节点名称。 -
建议修复措施——只读分诊到此结束。 报告最可能的单一原因(决策器类别 + 原文照录的
allocate_explanation)以及一条主要修复路径。根据颜色和分片角色匹配紧急程度。 黄色 / 副本未分配(无数据丢失):- 明确说明:所有主分片均已分配;仅副本缺失;无数据丢失。
- 指出真正的决策因素(例如
es-node-2上的磁盘高水位),而不只是说“某个节点离开了”。 - 建议:释放磁盘空间、扩展存储、添加数据节点,或在检查
GET /_cat/allocation后调整磁盘水位线。 - 不要建议:删除索引、使用
allocate_empty_primary、强制在正常主分片上分配,或在没有证据的情况下 重启整个集群。
红色 / 主分片未分配,且原因是
no_valid_shard_copy(有数据丢失风险):- 明确说明:有一个主分片未分配;该分片的查询/路由会失败;应将其视为紧急问题,且范围仅限于指定索引。
- 解释:唯一的副本位于已离开的节点上;由于其他剩余节点上都没有有效副本,Elasticsearch 无法分配主分片
(
can_allocate: no_valid_shard_copy)。 - 按以下顺序说明恢复路径:
- 如果已离开节点的数据目录完好,则将该节点恢复上线——分片副本会随之恢复。
- 从快照恢复到该索引(或恢复到新索引后再重新索引),前提是存在快照。
- **仅作为最后手段:**使用
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/health | elastic es cluster health |
GET /_cluster/health?level=indices | elastic es cluster health --level indices |
POST /_cluster/allocation/explain | elastic 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/allocation | elastic es cat allocation |
GET /_cat/recovery | elastic es cat recovery |
GET /_cat/shards/{index}?h=index,shard,prirep,state,unassigned.reason | elastic 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>' |