常见Elasticsearch分片分配故障排查指南

学习排查和解决常见的Elasticsearch分片分配故障。本指南涵盖识别未分配分片、诊断磁盘空间错误、节点不可用和分配过滤等问题,并提供可操作的解决方案和最佳实践,以维护健康的Elasticsearch集群。

常见Elasticsearch分片分配故障排查指南

分片分配故障是Elasticsearch从抽象走向具体的地方。集群健康状态变为黄色或红色,搜索开始返回部分结果,索引速度变慢,团队需要判断问题是磁盘、缺失节点、错误的分配规则还是损坏的分片数据。

我最常见到的错误是将所有未分配分片同等对待。计划重启后延迟的副本分片与主订单索引的未分配主分片紧急程度不同。首先找出哪个分片未分配,它是主分片还是副本分片,以及Elasticsearch对分配决策的说法。

正确解读健康信号

从集群健康开始:

GET /_cluster/health?pretty

重要字段包括 statusactive_primary_shardsactive_shardsrelocating_shardsinitializing_shardsunassigned_shardsdelayed_unassigned_shards

黄色表示所有主分片已分配,但一个或多个副本未分配。您的数据应仍可用,但冗余性降低。

红色表示一个或多个主分片未分配。这些分片中的数据不可用,除非Elasticsearch能提升副本、恢复拥有该分片的节点或从快照恢复。

如果 relocating_shardsinitializing_shards 非零,集群可能已在自我修复。不要仅仅因为颜色暂时变黄就中断正常恢复。

列出未分配分片

使用 _cat/shards 查看具体问题:

GET /_cat/shards?v&h=index,shard,prirep,state,node,unassigned.reason&s=state,index

查找 UNASSIGNEDprirep 列告诉您分片是主分片(p)还是副本(r)。unassigned.reason 列给出简短原因,如 NODE_LEFTINDEX_CREATEDCLUSTER_RECOVEREDALLOCATION_FAILED

对于大型集群,缩小范围:

GET /_cat/shards/logs-*?v&h=index,shard,prirep,state,node,unassigned.reason

一旦获得索引、分片编号和主/副本标志,向Elasticsearch请求真实解释。

使用分配解释API

对于任何当前未分配的分片:

GET /_cluster/allocation/explain
{}

对于特定分片:

GET /_cluster/allocation/explain
{
  "index": "logs-2026.05.24",
  "shard": 0,
  "primary": false
}

阅读 can_allocateallocate_explanationunassigned_infonode_allocation_decisions。节点决策特别有用,因为它们显示每个节点被拒绝的原因。常见决策器包括磁盘阈值、同分片规则、分配过滤器、感知规则和每节点总分片数限制。

如果输出显示主分片 no_valid_shard_copy,请认真对待。Elasticsearch当前看不到该主分片的可用副本。

原因1:没有足够的合适节点

一个简单的单节点集群带一个副本将永远保持黄色。Elasticsearch不会将副本放在与主分片相同的节点上。一个三节点集群配置了两个副本的索引需要三个合适的数据节点。如果分配感知要求副本必须分布在不同的区域,您还需要在所需区域有足够的节点。

检查副本设置:

GET /my-index/_settings?filter_path=*.settings.index.number_of_replicas

如果这是实验室或临时环境,减少副本:

PUT /my-index/_settings
{
  "index": {
    "number_of_replicas": 0
  }
}

对于生产环境,更好的答案通常是添加合适的数据节点或调整不切实际的副本数。降低副本会移除冗余。

原因2:磁盘水位线

磁盘压力是最常见的分配阻塞因素之一。Elasticsearch使用磁盘水位线来避免节点填满。当节点超过阈值时,Elasticsearch可能停止向它们分配分片,并可能将分片移走。

检查分配和磁盘使用情况:

GET /_cat/allocation?v
GET /_cat/nodes?v&h=name,ip,disk.used_percent,disk.avail,heap.percent,ram.percent,node.role

分配解释输出可能显示节点高于低或高磁盘水位线。如果索引达到洪水阶段条件,Elasticsearch还可能在受影响的索引上设置写入块。

好的修复是容量修复:确认快照后删除旧索引、添加磁盘、添加数据节点、将数据移到另一层,或通过索引生命周期管理缩短保留期。

在受控紧急情况下更改水位线可能是合理的,但这并非容量计划。如果每个数据节点几乎已满,提高阈值只会让集群更接近故障运行。

从洪水阶段事件释放空间后,检查只读块:

GET /my-index/_settings?filter_path=*.settings.index.blocks.write,*.settings.index.blocks.read_only_allow_delete

仅在磁盘压力解决后移除块:

PUT /my-index/_settings
{
  "index.blocks.read_only_allow_delete": null
}

原因3:维护后禁用分配

团队经常在滚动维护期间禁用分配,然后忘记重新启用。

检查集群设置:

GET /_cluster/settings?include_defaults=true&pretty

查找 cluster.routing.allocation.enable。值包括 allprimariesnew_primariesnone。如果是 none,副本和可能其他分片移动将不会正常分配。

重新启用分配:

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

同时检查 transient 设置。即使持久部分看起来正常,临时维护设置仍可能影响集群。

原因4:限制性分配过滤器

索引级过滤器可以将索引固定到某些节点:

GET /my-index/_settings?filter_path=*.settings.index.routing.allocation.*

集群级过滤器可以排除节点分配:

GET /_cluster/settings?include_defaults=true&filter_path=**.cluster.routing.allocation.*

节点属性也很重要:

GET /_cat/nodeattrs?v

典型的故障如下:索引需要 box_type: hot,但热节点已被替换,新节点没有 node.attr.box_type: hot。Elasticsearch严格遵循规则;规则现在错了。

要移除过于严格的索引过滤器:

PUT /my-index/_settings
{
  "index.routing.allocation.require.box_type": null,
  "index.routing.allocation.include.box_type": null,
  "index.routing.allocation.exclude.box_type": null
}

使用索引中存在的确切设置名称。如果分配规则编码了真实的区域或层要求,不要盲目清除它们。

原因5:节点离开后的延迟分配

当节点离开时,Elasticsearch可能延迟分配副本分片,因为节点可能很快回来。这避免了在正常重启期间通过网络复制大型分片。

检查延迟分片:

GET /_cluster/health?pretty

如果 delayed_unassigned_shards 大于零且节点预计会回来,等待可能是最佳操作。您也可以检查索引设置:

GET /my-index/_settings?filter_path=*.settings.index.unassigned.node_left.delayed_timeout

默认通常为一分钟,但始终检查您的集群和版本。一些团队为大型分片的计划滚动重启增加此值。不要让它太长,以至于真正的故障导致副本长时间缺失。

原因6:节点上分片过多

index.routing.allocation.total_shards_per_node 可以限制来自同一索引的分片可以位于同一节点上的数量。集群级分片限制也可能适用。这些设置很有用,但它们可能在小集群中阻塞分配。

检查索引设置:

GET /my-index/_settings?filter_path=*.settings.index.routing.allocation.total_shards_per_node

如果您有五个主分片、一个副本、两个数据节点和较低的每节点限制,Elasticsearch可能没有合法位置。修复限制、添加节点或重新设计分片数量。

原因7:主分片没有有效副本

这是可怕的情况。分配解释可能报告主分片没有有效分片副本。也许拥有主分片的唯一节点已消失。也许磁盘故障。也许分片数据已损坏。

首先,如果缺失节点预计会返回,尝试恢复它。检查系统日志、Elasticsearch日志、磁盘健康和网络连接。如果存在有效副本,Elasticsearch通常应提升它。

如果没有有效副本,从快照恢复:

POST /_snapshot/my_repository/snapshot_name/_restore
{
  "indices": "affected-index"
}

如果数据可以从源系统重建且您接受丢失分片内容,allocate_empty_primary 可用,但这是数据丢失操作:

POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_empty_primary": {
        "index": "affected-index",
        "shard": 0,
        "node": "target-node",
        "accept_data_loss": true
      }
    }
  ]
}

除非您有意识地决定丢失的数据已消失或可重建,否则不要使用此方法“使集群变绿”。

监控恢复

做出更改后,监控进度:

GET /_cat/recovery?v&active_only=true
GET /_cat/shards?v&h=index,shard,prirep,state,node,unassigned.reason
GET /_cluster/health?pretty

大型分片需要时间。如果字节计数在 _cat/recovery 中移动,集群正在工作。如果没有任何变化,再次检查分配解释。Elasticsearch的决策可能在您第一次修复后发生变化,揭示下一个阻塞因素。

真正有帮助的预防措施

在达到水位线之前监控磁盘。对趋势发出警报,而不仅仅是磁盘满。

对日志和指标使用ILM或数据流,以便自动保留。

保持快照最新并测试恢复。从未恢复过的快照只是希望。

保持分片大小和分片数量合理。太多小分片会使分配和恢复比数据量所暗示的更慢。

记录分配过滤器和节点属性。六个月后,有人会替换节点并忘记使索引可分配的属性。

将黄色视为警告,红色视为事件。黄色在维护期间可以接受,但不应成为背景噪音。红色意味着至少一个主分片不可用,等待时间越长,可用的简单恢复选项可能越少。

事件现场检查清单

当分片分配中断时,每次都收集相同的证据。这可以防止团队在不同理论之间跳跃。

运行:

GET /_cluster/health?pretty
GET /_cat/nodes?v&h=name,ip,roles,master,disk.used_percent,heap.percent,ram.percent
GET /_cat/shards?v&h=index,shard,prirep,state,node,unassigned.reason&s=state,index
GET /_cat/allocation?v
GET /_cat/recovery?v&active_only=true
GET /_cluster/settings?include_defaults=true&pretty

然后对代表性的未分配分片运行分配解释。如果有许多,按原因分组。十个因磁盘水位线阻塞的未分配副本是一个问题。三个带有 no_valid_shard_copy 的主分片是另一个问题。

记录受影响数据是否可以重建。来自上游队列的日志、来自代理的指标和派生搜索索引可能可以从源系统恢复。用户创建的内容或合规记录可能不行。恢复命令应遵循该业务现实。

何时等待,何时行动

当恢复正在积极进行、缺失节点预计很快回来或延迟分配正在执行您配置的操作时等待。您可以通过 _cat/recovery 验证进度;移动的字节计数和文件计数是好迹象。

当分配解释显示永久阻塞时行动:没有合适的节点、每个节点上的磁盘水位线、分配被禁用、缺失节点属性或没有有效分片副本。等待不会修复拒绝每个节点的规则。

当重要索引的主分片未分配时迅速升级。副本故障降低安全性。主故障降低可用性。

避免使恢复变慢

大型恢复与正常搜索和索引竞争。一次添加太多节点、重启更多节点或在不检查磁盘和网络容量的情况下提高恢复并发性可能使集群更不稳定。

如果您调整恢复设置,有意识地执行并记录原始值。并发恢复等设置在某些环境中可能有帮助,在其他环境中可能有害。理论上更快的恢复可能使磁盘过载并增加查询延迟,以至于用户经历更严重的停机。

关注热点节点。由于分片大小、层规则或磁盘使用不均,分配可能在技术上成功,同时将过多工作放在一个节点上。使用 _cat/allocation、节点统计和监控系统确认集群在立即故障清除后是平衡的。

事后修复

大多数分片分配事件都有预防故事。磁盘水位线事件指向保留、ILM或容量规划。分配过滤器事件指向缺失的运行手册文档。无有效副本事件指向快照和上游重放。慢恢复指向分片大小和硬件。

不要仅仅因为健康状态变绿就关闭事件。移除临时副本更改、恢复正常刷新间隔、重新启用分配(如果已更改)、验证快照并添加本可以更早捕获问题的警报。

特殊情况:关闭和隐藏索引

有时索引未分配是因为它已关闭、隐藏或属于您未意识到正在触及的系统功能的一部分。当存在系统索引时,小心使用宽泛的通配符命令。在现代集群中,安全、Kibana、转换和其他堆栈功能可能维护自己的索引。

使用窄模式,并且仅在您打算检查时包含隐藏索引。如果系统索引有分配问题,请检查相关堆栈组件日志以及Elasticsearch。例如,Kibana保存对象索引问题可能表现为Elasticsearch分片分配问题和Kibana启动失败。

规则与用户数据相同:确定确切索引,了解谁拥有它,然后选择修复。除非您了解产品级影响,否则不要删除或强制分配系统索引以清除红色健康状态。