4. 集群健康与故障检测
Elasticsearch 的集群健康状态是运维人员最先接触、也最容易被误读的指标。它只有三个取值:green、yellow、red,但三者背后对应的是分片分配状态的不同组合,而不是集群整体性能的好坏。理解判定逻辑,才能避免"看到 yellow 就重启集群"这类危险操作。
一、健康状态的判定逻辑
集群健康由主节点根据主分片(primary shard)和副本分片(replica shard)的分配情况计算得出,判定规则非常明确:
- green:所有索引的主分片和副本分片都已成功分配到节点上,集群功能完整。
- yellow:所有主分片均已分配,但至少有一个副本分片未分配。数据可读可写,但缺少冗余,节点故障时存在数据丢失风险。
- red:至少有一个主分片未分配,对应索引的部分数据不可读写,属于严重故障。
需要注意,健康状态是集群级别的聚合结果,取所有索引中最差的状态。只要有一个索引是 red,整个集群就是 red。因此排查时不能只看集群状态,必须下钻到索引和分片级别。
GET _cluster/health,返回 status、number_of_nodes、active_primary_shards、active_shards、unassigned_shards 等字段。查看索引级健康:
GET _cluster/health?level=indices。查看分片级详情:
GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason。
二、故障检测机制
Elasticsearch 的故障检测依赖两层心跳:主节点与数据节点之间的心跳,以及节点之间的故障探测。核心参数是 cluster.fault_detection.leader_check.interval(默认 1s)和 cluster.fault_detection.follower_check.interval(默认 1s)。
主节点会周期性向所有节点发送 leader check,若连续多次未收到响应,则判定该节点失联,将其从集群状态中移除,并触发分片重新分配。默认情况下,节点失联判定阈值约为 30 秒(由 cluster.fault_detection.leader_check.timeout 与重试次数共同决定)。
节点失联后,主节点会执行以下动作:
- 将该节点标记为不可用,从集群状态中移除。
- 该节点上的主分片被标记为未分配,触发主分片重新选举或提升副本。
- 若存在可用副本,副本被提升为主分片,集群状态可能从 green 变为 yellow。
- 若没有可用副本,主分片保持未分配,集群变为 red。
三、节点失联与恢复流程
节点恢复上线后,会重新加入集群。此时主节点会检查该节点上的分片数据是否与当前主分片一致:若一致,直接作为副本加入;若落后,则通过分片恢复(peer recovery)从主分片同步差异数据。恢复期间,分片状态为 INIT 或 RELOCATING,可通过 GET _cat/recovery?v 观察进度。
恢复完成后,副本分片重新分配,集群健康状态回到 green。若恢复过程中再次发生节点失联,主节点会重新触发分配,可能造成反复恢复,此时应检查网络稳定性和 cluster.routing.allocation 相关配置。
四、常见健康问题的排查方法
场景一:yellow 且 unassigned_shards 长期不降。常见原因是副本数大于可用节点数,或节点被分配过滤规则排除。排查步骤:
GET _cluster/allocation/explain
{
"index": "logs-2024",
"shard": 0,
"primary": false
}
返回结果中的 unassigned_info.reason 会直接说明原因,例如 NODE_LEFT、ALLOCATION_FAILED、CLUSTER_RECOVERED。若为 NODE_LEFT 且节点已恢复,通常等待自动分配即可;若为 ALLOCATION_FAILED,需检查磁盘水位、分片大小和 index.routing.allocation 设置。
场景二:red 且主分片未分配。这是最严重的情况。首先确认该主分片是否有可用副本:
GET _cat/shards/logs-2024?v&h=index,shard,prirep,state,node,unassigned.reason
若存在 STARTED 的副本,主节点会自动提升其为主分片,集群恢复为 yellow。若所有副本均不可用,则只能等待原节点回归,或使用 POST _cluster/reroute 手动分配。手动分配前必须确认目标节点上存在该分片的完整数据,否则会造成数据丢失。
allocate_empty_primary 强制分配空主分片,这会导致该分片上的历史数据永久丢失。仅在确认数据可丢弃时使用。
场景三:节点频繁失联。若日志中反复出现 master_left 或 node_left,应检查网络延迟、GC 停顿和 cluster.fault_detection 参数。对于跨机房部署,可适当调大 leader_check.timeout,避免因短暂网络抖动误判失联。
五、排查清单
| 现象 | 优先检查 | 常用命令 |
|---|---|---|
| yellow 持续 | 副本数 vs 节点数、分配过滤规则 | _cluster/allocation/explain |
| red 主分片未分配 | 是否有可用副本、节点是否回归 | _cat/shards |
| 节点频繁失联 | 网络延迟、GC、心跳超时 | _cat/nodes?v、节点日志 |
| 恢复缓慢 | 恢复限流、磁盘 IO | _cat/recovery?v |