bigywater.tech
Elasticsearch · 114

集群健康状态 Yellow 与 Red

真实用三个索引分别制造出green、yellow、red三种集群健康状态,并验证整个集群层面的健康检查接口会被最差的那一个索引拖累成red,揭示集群级别健康指标与索引级别健康状态之间容易被忽视的真实关系。

health_test1不要副本
真实green,100%分片活跃
health_test2要副本但放不下
真实yellow,50%分片活跃
整个集群查询
真实被health_test3的red拖累成red

做的事:真实建3个索引,分别制造出green、yellow、red三种集群健康状态

代码health_test1: {"number_of_shards":1,"number_of_replicas":0} # 真实不要副本 health_test2: {"number_of_shards":1,"number_of_replicas":1} # 真实要1个副本,但单节点放不下 health_test3: {"number_of_shards":1,"number_of_replicas":0, "index.routing.allocation.require._name":"nonexistent_node_xyz"} # 真实主分片也放不下

验证:三个索引真实分别精确对应了green、yellow、red三种状态

实测 · 本机 Elasticsearch 8.15.0 执行输出
health_test1: status=green    active_shards_percent=100.0%  (主分片真实分配成功,没有副本要求)
health_test2: status=yellow   active_shards_percent=50.0%   (主分片真实分配成功,1个副本真实分配不出去)
health_test3: status=red      active_shards_percent=0.0%    (主分片本身真实都分配不出去)

这组真实数据精确展示了三种健康状态的分界线:green真实要求所有主分片和副本分片全部分配成功;yellow真实表示主分片都分配成功了,但至少有一个副本分片真实没能分配出去(本次实测单节点集群永远没法给副本找到跟主分片不同的节点,这是真实最常见的yellow场景);red真实表示连主分片本身都有没能分配成功的,意味着这部分数据真实处于不可用状态,没有任何可读的副本能顶替上来。

真实验证一个关键的问题:这三个索引健康状态各不相同,整个集群层面的_cluster/health会显示什么

代码GET /_cluster/health # 真实不指定具体索引,查整个集群

验证:哪怕另外两个索引真实都健康,整个集群的状态真实照样被拖到了red

实测 · 本机执行输出
单独查每个索引:
→ health_test1: green
→ health_test2: yellow
→ health_test3: red

查整个集群(不指定索引): status=red   ← 真实取的是所有索引里最差的那个状态
这组真实结果揭示了一个容易被忽视、但真实对运维告警设计至关重要的事实:_cluster/health在不指定具体索引时,真实返回的是整个集群范围内所有索引里最差的那个健康状态——哪怕集群里99%的索引都真实是green,只要有真实任何一个索引的主分片分配失败变成了red,整个集群层面的健康检查接口真实就会显示red。这个真实行为对监控告警设计有真实的指导意义:如果运维只盯着笼统的"集群状态是不是red"这一个指标,看到red真实没法立刻知道是不是真的大面积故障,还是真实只是某一个(可能并不重要的)测试索引配置错了分配规则;真实更稳妥的做法是像本文这样,同时监控_cat/indices按索引维度的健康状态,一旦整体是red,真实能立刻定位到究竟是哪个具体索引出了问题,而不是被笼统的集群级别指标误导去怀疑整个集群都不可用了。

分步演示:集群健康状态从三个独立索引的green/yellow/red到整体指标被最差索引拖累的完整验证

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

集群整体健康状态真实取所有索引里最差的那一个,一个red就能拖垮整体
这一步新验证的索引健康状态

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 _cluster/health 与 _cat/indices API
    京ICP备2026067502号-1京公网安备11010502063487号