集群健康状态显示红色或黄色,表示一个或多个分片没有分配到节点。
- 红色:集群中存在未分配的主分片,搜索和索引等操作可能因此失败。
- 黄色:所有主分片都已分配,但有一些副本分片尚未分配。这会增加数据丢失风险,并可能降低集群性能。
健康状态为红色或黄色时,集群仍会尽可能处理搜索与索引请求,但可能推迟某些管理和清理活动,直到健康状态恢复为绿色。例如:
- 某些索引生命周期管理(ILM)操作要求目标索引的健康状态为绿色。
- Kibana 需要其依赖的底层系统索引为绿色才能加载,否则会返回
Kibana server is not ready yet错误。
在许多情况下,集群会自动恢复为绿色。如果没有自动恢复,就必须手动解决遗留问题,让管理和清理活动能够继续。这段视频 演示了如何监控分配健康状态。
通过 AutoOps 检测和解决问题
AutoOps 是一种监控工具,可以实时检测 Elasticsearch 集群中的问题,并提供解决问题和改善性能的建议。请参阅 AutoOps 介绍。
诊断集群状态
检查集群状态
使用集群健康 API:
GET _cluster/health?filter_path=status,*_shards
健康集群的 status 为 green,unassigned_shards 为零。yellow 表示只有副本分片未分配;red 表示一个或多个主分片未分配。
提示:对于 Elastic Cloud Enterprise 和 Elastic Cloud Hosted 部署,也可以在 Elastic Cloud Console 或 ECE Cloud UI 中,通过部署的“Monitoring”页面检查健康状况。该页面提供健康问题、受影响范围与故障排查支持的详细信息。更多信息见 云部署健康状况。
查看未分配的分片
使用 cat shards API:
GET _cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state
未分配分片的 state 为 UNASSIGNED。prirep 的值为 p 时表示主分片,为 r 时表示副本分片。
要了解分片为什么没有分配,以及必须采取什么操作才能让 Elasticsearch 分配它,请使用集群分配解释 API:
GET _cluster/allocation/explain?filter_path=index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*
{
"index": "my-index",
"shard": 0,
"primary": false
}
常见响应示例见 使用集群分配 API 排查问题。
修复红色或黄色健康状态
分片可能因多种原因处于未分配状态。以下内容介绍最常见的原因及解决办法。
单节点集群
Elasticsearch 永远不会将副本分片分配到对应主分片所在的同一个节点上。单节点集群因此始终会显示黄色。若要变为绿色,必须将所有索引的 number_of_replicas 设为 0。只有在理解无副本运行的影响,即容错能力与恢复选择减少之后,才能这样做。
同样,如果副本数量等于或超过节点数量,就会有部分分片无法分配。
恢复丢失的节点
数据节点离开集群时,分片常常会变成未分配状态。可能的原因包括:
- 手动重启节点会使集群暂时处于不健康状态,直到节点恢复。
- 节点过载或故障可能暂时破坏集群健康状态。内存不足错误,或高强度搜索期间的高内存使用量,可能导致长时间垃圾回收(GC)暂停,进而触发这种情况。有关 JVM 的其他问题,见下文“降低 JVM 内存压力”。
- 网络问题可能使节点无法可靠通信,导致分片不同步。检查日志中是否反复出现节点离开并重新加入集群的消息。
解决问题并恢复节点后,节点会重新加入集群。Elasticsearch 随后自动分配所有未分配的分片。
可以通过查看集群健康状态监控这一过程。未分配分片的数量应逐步减少,直到状态恢复为绿色。
为避免因暂时性问题浪费资源,Elasticsearch 默认将分配延迟一分钟。如果节点已恢复,而你不想等待延迟结束,可以不带参数调用集群 reroute API,启动分配过程。这个过程在后台异步执行。
POST _cluster/reroute
修正分配设置
错误的分配设置可能导致主分片无法分配,相关设置包括:
使用获取索引设置与获取集群设置 API,查看当前分配设置:
GET my-index/_settings?flat_settings=true&include_defaults=true
GET _cluster/settings?flat_settings=true&include_defaults=true
可以通过更新索引设置与更新集群设置 API 修改这些设置。
分配副本或减少副本数量
为防范硬件故障,Elasticsearch 不会把副本分配到对应主分片所在的节点上。如果没有其他可容纳副本的数据节点,它就会一直未分配。可以采用以下办法:
- 在同一数据层中添加数据节点,用来承载副本。
- 修改索引设置
index.number_of_replicas,减少每个主分片的副本数量。为了高可用性,建议每个主分片至少保留一个副本。
PUT _settings
{
"index.number_of_replicas": 1
}
释放或增加磁盘空间
Elasticsearch 使用磁盘低水位阈值,确保数据节点有足够空间接收分片。默认情况下,不会将分片分配到磁盘使用率超过 85% 的节点。
通过 cat allocation API 检查节点当前的磁盘空间:
GET _cat/allocation?v=true&h=node,shards,disk.*
如果节点空间不足,可以选择:
- 升级节点,增加磁盘容量。
- 向集群添加更多节点。
- 删除不再需要的索引以释放空间。使用 ILM 时,可以更新生命周期策略,采用可搜索快照或添加删除阶段。如果不再需要搜索这些数据,可以通过快照将它们存储到集群之外。
- 如果索引不再写入数据,可使用 force merge API 或 ILM 的 force merge 操作,将它的段合并为更大的段。
POST my-index/_forcemerge
如果索引是只读的,可以使用 shrink index API 或 ILM 的 shrink 操作,减少其主分片数量。
POST my-index/_shrink/my-shrunken-index
如果节点磁盘容量很大,可以提高磁盘低水位阈值,或者将它设置为明确的字节值。
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%"
}
}
重要:提高阈值通常只是临时解决办法。如果不释放磁盘空间,可能导致集群不稳定。
重新启用分片分配
在重启或其他集群维护期间,通常会禁用分片分配,以防节点暂时离开集群时触发连锁恢复。如果维护结束后没有重新启用,Elasticsearch 就无法分配分片。
使用集群设置 API 确认分配是否被禁用:
GET _cluster/settings?include_defaults=true&filter_path=*.cluster.routing.allocation.enable
如果未启用分配,响应会在 persistent 或 transient 层级显示对默认值的覆盖,例如:
{
"persistent": {
"cluster": {"routing": {"allocation": {"enable": "none" } } }
},
"defaults": {
"cluster": {"routing": {"allocation": {"enable": "all" } } } }
}
注意:cluster.routing.allocation.enable 仅影响今后的分片分配,不会改变现有分配。因此,将它覆盖为 none 不会阻止现有数据摄入。但覆盖期间无法创建新索引,包括 ILM Rollover 触发创建的索引。
要重新启用分配,请重置集群设置 cluster.routing.allocation.enable:
PUT _cluster/settings
{
"persistent" : {
"cluster.routing.allocation.enable" : null
}
}
重新启用后,集群会自动恢复分片分配、恢复和再平衡。可以使用集群健康 API 查看状态:
GET _cluster/health
这段视频演示了如何排查“no allocations are allowed”问题。
降低 JVM 内存压力
分片分配需要 JVM 堆内存。过高的 JVM 内存压力可能触发熔断器,使分配停止,分片因此保持未分配状态。请参阅 JVM 内存压力过高。
恢复丢失主分片的数据
如果包含主分片的节点丢失,Elasticsearch 通常可以利用另一个节点上的副本替换它。如果无法恢复节点,而且副本不存在或不可恢复,Allocation Explain 将报告 no_valid_shard_copy,此时必须选择以下方案之一:
- 从快照恢复缺失数据。
- 从原始数据源重新索引缺失数据。
- 运行 Delete Index,在整个索引层面接受数据丢失。
- 执行 Cluster Reroute 的
allocate_stale_primary或allocate_empty_primary命令,并设置accept_data_loss: true,在分片层面接受数据丢失。
警告:只有在节点已经不可能恢复时,才能使用下面的选项。它会分配一个空的主分片。如果原节点后来重新加入集群,Elasticsearch 会用这个较新的空分片数据覆盖原主分片,从而造成数据丢失。
POST _cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "my-index",
"shard": 0,
"node": "my-node",
"accept_data_loss": "true"
}
}
]
}
这段视频演示了如何排查 no_valid_shard_copy。
原文:Red or yellow cluster health status。作者/维护者:Elastic 文档团队。本文为原文的中文译文;代码保留原文内容。











暂无评论内容