📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 6.8-8.9

1. 错误异常的基本描述 #

all shards failed 是 Elasticsearch 搜索阶段的汇总性异常,表示这次查询命中的所有目标分片都没有成功返回结果。它通常不是最原始的错误,而是协调节点在汇总各分片执行结果时给出的最终结论。真正的根因往往藏在 failed_shards 里的具体异常里,例如字段类型不支持、聚合执行失败、脚本报错、分片不可用、索引关闭或节点异常。

这类错误最容易误判的地方在于,用户往往只看到一句 all shards failed,但真正需要排查的是“为什么每个分片都失败了”。因此定位时不能停留在报错标题,而要继续向下看失败分片的索引名、分片号、异常类型和具体 reason

常见现象 #

  • 在执行 _search、Kibana 可视化、大盘查询或带聚合的检索请求时,接口直接返回 search_phase_execution_exception,其中 reasonall shards failed
  • 返回体中通常会带有 failed_shards 数组,里面列出失败的索引、分片编号和分片级错误原因;如果跨多个索引查询,往往多个分片会因为同一种 DSL 或字段问题一起失败。
  • 某些查询在小范围索引或测试环境正常,但在生产环境、长时间范围或跨索引查询时失败,这通常说明问题与字段映射不一致、历史脏数据或部分分片状态异常有关。
  • 从业务侧看,典型表现包括搜索页无结果、可视化报表打不开、聚合统计失败、告警规则查询报错,而不是单纯的“节点连不上”。

典型报错与异常栈 #

这类错误常与下面这些异常一起出现:

  • search_phase_execution_exception
  • query_shard_exception
  • aggregation_execution_exception
  • illegal_argument_exception
  • script_exception
  • index_closed_exception
  • no_shard_available_action_exception

常见日志形态通常类似下面这样:

{
    "error": {
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "failed_shards": [
            {
                "shard": 0,
                "index": "logs-2026.03.31",
                "reason": {
                    "type": "illegal_argument_exception",
                    "reason": "Fielddata is disabled on text fields by default"
                }
            }
        ]
    },
    "status": 400
}

也可能在服务端日志中看到类似堆栈:

SearchPhaseExecutionException: all shards failed
Caused by: QueryShardException / AggregationExecutionException / ScriptException
at org.elasticsearch.action.search...

2. 为什么会发生这个错误 #

这个错误的本质不是“所有分片同时坏了”,而是“这条查询对所有命中的分片都不成立或都执行失败了”。如果 DSL 本身有问题、字段不支持当前查询能力、跨索引 mapping 不一致,或者命中的分片本身不可用,那么每个分片都会独立失败,最终由协调节点统一汇总为 all shards failed

常见原因通常包括:

  • text 字段做排序、聚合或脚本访问,而字段本身没有开启 fielddata,或者应该使用 .keyword 子字段却误用了主字段。
  • 跨多个索引查询时,同名字段在不同索引上的 mapping 不一致,例如一个索引是 keyword,另一个是 textlong,导致所有相关分片都无法按同一种逻辑执行。
  • 查询命中了关闭索引、不可用分片、恢复中的分片,或者集群处于 red/异常迁移状态,导致所有目标分片都没有返回有效结果。
  • 使用了错误的聚合、脚本、nested 路径或不兼容的查询子句,导致每个分片都会在本地执行阶段抛出相同异常。
  • 节点资源异常,例如 JVM 堆紧张、断路器触发、线程池拥塞、底层 IO 问题,导致查询在所有相关分片上都失败。

3. 如何排查和解决这个异常和解决这个异常 #

建议按“先拿到失败分片明细,再缩小查询范围,最后确认是 DSL 问题还是分片状态问题”的顺序处理:

  1. 保留原始 _search 请求和完整错误返回,重点提取 failed_shards 中的 indexshardtypereason
  2. 缩小查询范围,例如先查单个索引、较短时间范围,判断是所有索引都失败,还是某个索引家族有问题。
  3. 检查字段 mapping 和 field caps,确认参与排序、聚合、脚本或过滤的字段在所有命中索引上是否一致可用。
  4. 再看集群健康度、分片分布和节点资源,确认是否存在未分配分片、关闭索引或节点压力异常。
  5. 如果查询里用了复杂聚合、脚本或 nested,优先逐步删减 DSL,找出最小触发条件。

相关 Elasticsearch API 及调用说明 #

下面这些接口最适合排查 all shards failed。建议从原始查询和 failed_shards 入手,再核对字段能力、分片状态和节点资源。

1. 复现原始搜索请求 #

用于确认是哪条查询导致所有分片失败。

curl -X GET "http://localhost:9200/my_index/_search?pretty" \
    -H 'Content-Type: application/json' \
    -d '{
        "query": {
            "match": {
                "message": "error"
            }
        },
        "aggs": {
            "by_host": {
                "terms": {
                    "field": "host.name"
                }
            }
        }
    }'

重点不是只看顶层报错,而是查看返回体里的 failed_shards

2. 校验字段能力 #

用于确认跨索引查询时,同名字段是否都支持聚合、排序或搜索。

curl -X GET "http://localhost:9200/logs-*/_field_caps?fields=host.name,message,user.keyword&pretty"

重点关注:

  • 字段在不同索引上是否类型一致。
  • 是否同时出现 textkeywordlong 等不兼容类型。
  • 字段是否支持 aggregatablesearchable

3. 查看字段 mapping #

如果怀疑某个字段在部分索引上 mapping 漂移,可以直接查看:

curl -X GET "http://localhost:9200/logs-*/_mapping/field/host.name?pretty"

如果问题字段很明确,这个接口比看完整 _mapping 更高效。

4. 校验查询是否合法 #

用于先排除明显的 DSL 结构问题。

curl -X GET "http://localhost:9200/my_index/_validate/query?pretty&explain=true" \
    -H 'Content-Type: application/json' \
    -d '{
        "query": {
            "match": {
                "message": "error"
            }
        }
    }'

这个接口不能替代真实搜索执行,但可以先排掉部分结构错误。

5. 查看集群健康状态 #

用于判断问题是否和分片整体状态有关。

curl -X GET "http://localhost:9200/_cluster/health?pretty"

重点关注:

  • status 是否为 yellowred
  • unassigned_shards 是否大于 0
  • relocating_shardsinitializing_shards 是否异常偏高。

6. 查看分片分布和状态 #

用于确认失败是否集中在某些索引或节点。

curl -X GET "http://localhost:9200/_cat/shards?v"

如果已定位到具体索引:

curl -X GET "http://localhost:9200/_cat/shards/my_index?v"

重点关注:

  • 是否存在 UNASSIGNEDINITIALIZINGRELOCATING
  • 失败分片是否集中在同一节点。
  • 主分片是否正常 STARTED

7. 查看未分配分片解释 #

如果有未分配分片,可以继续看原因:

curl -X GET "http://localhost:9200/_cluster/allocation/explain?pretty" \
    -H 'Content-Type: application/json' \
    -d '{
        "index": "my_index",
        "shard": 0,
        "primary": true
    }'

这个接口适合确认是磁盘水位、节点过滤条件,还是恢复失败导致分片不可用。

8. 查看节点资源状态 #

用于判断搜索失败是否与 JVM、断路器或线程池压力有关。

curl -X GET "http://localhost:9200/_nodes/stats/jvm,fs,thread_pool,breaker?pretty"

重点关注:

  • breaker 是否频繁触发。
  • 搜索线程池是否积压。
  • 个别节点是否存在明显的堆或磁盘异常。

9. 查看热点线程或任务 #

如果查询很慢后才报 all shards failed,可以进一步看:

curl -X GET "http://localhost:9200/_nodes/hot_threads?pretty"
curl -X GET "http://localhost:9200/_tasks?pretty&actions=*search"

这两个接口适合判断是否存在高开销查询、脚本热点或长期阻塞的搜索任务。

排查时需要注意的问题 #

  • 不要把 all shards failed 当成根因,它只是最终汇总结果;真正需要看的永远是 failed_shards.reason
  • 如果查询跨多个时间分区索引,先缩小索引范围通常能最快定位是哪个索引的 mapping 或数据有问题。
  • 如果是 Kibana 或上层应用拼装的查询,务必抓取最终发往 Elasticsearch 的原始 DSL,而不是只看业务代码里的模板。

4. 如何解决这个错误 #

常用修复思路 #

  • 如果根因是字段类型或字段能力不匹配,优先改用正确字段,例如从 text 改为 keyword,必要时通过重建索引统一 mapping。
  • 如果根因是查询 DSL 过重或写法错误,先简化聚合、排序和脚本逻辑,确认最小可用查询后再逐步恢复功能。
  • 如果根因是分片或索引状态异常,先恢复分片可用性、重新分配或处理关闭索引,再恢复查询。
  • 如果根因是节点资源不足,先缓解 JVM、线程池和断路器压力,必要时扩容节点或对高风险搜索流量做限流。

后续注意事项与推荐建议 #

  • 为跨索引查询建立字段规范和模板约束,尽量避免同名字段在不同索引上出现不同类型。
  • 对高频聚合、脚本查询和复杂报表建立上线前检查,避免高风险 DSL 直接进入生产环境。
  • failed_shards、慢查询、断路器和分片异常建立告警,尽量在用户看到 all shards failed 之前就发现问题。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 适合同时观察分片健康、节点资源、慢查询和失败趋势,快速判断这是单个索引问题还是全局查询问题。
  • INFINI Gateway 适合在入口侧采样原始 DSL,请求失败时可以更快回溯到底是哪类查询触发了 all shards failed
  • 如果这类问题反复出现,建议把失败 DSL、来源应用、目标索引和失败分片信息统一沉淀为排障画像,后续定位会快很多。

5. 小结 #

all shards failed 不是一个具体的底层故障类型,而是“所有目标分片都失败了”这一最终结果。真正的排查重点永远是失败分片里的具体异常、涉及的字段、相关索引和分片状态。

只要坚持“先看 failed_shards,再查 mapping 与分片,再判断资源与 DSL”这条路径,这类问题通常都能很快缩小范围。对于频繁出现的场景,结合 INFINI Console 和 INFINI Gateway 做查询观测与索引治理,会比事后被动排查更有效。

相关错误 #

附:日志上下文 #

下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:

SearchPhaseExecutionException: all shards failed
    at org.elasticsearch.action.search.AbstractSearchAsyncAction.onPhaseFailure(...)
    at org.elasticsearch.action.search.SearchScrollAsyncAction...
Caused by: [index_name][shard_id] ShardSearchFailure
    ...