0%

健康状态red问题查找

Elasticsearch 索引健康状态为 Red 的排查与解决方案

当 Elasticsearch 索引健康状态显示为 red 时,表示至少有一个主分片未分配(无法使用),这会导致部分或全部数据不可访问。本文以实际案例讲解如何定位 red 状态的根源(如磁盘空间不足、分片分配失败等),并提供针对性解决方案。

Red 状态的核心原因

Elasticsearch 集群健康状态分为三级:

  • green:所有主分片和副本分片均正常分配。
  • yellow:所有主分片正常分配,但至少有一个副本分片未分配。
  • red:至少有一个主分片未分配(数据不可用)。

red 状态的常见触发因素

  • 主分片所在节点宕机且无副本可用。
  • 分片分配失败(如磁盘空间不足、权限问题、配置冲突)。
  • 索引损坏或数据文件丢失。
  • 节点资源不足(内存、CPU 超限)。

排查步骤:从整体到细节

查看集群与索引健康状态

首先通过 _cluster/health 确认问题范围(是单个索引还是整个集群):

1
2
# 查看集群健康,包含索引级别的状态
GET _cluster/health?level=indices

响应示例(某索引为 red):

索引层级健康状态

关键:锁定状态为 red 的索引(如 problem_index)。

检查分片状态与未分配原因

通过 _cat/shards 查看具体分片的状态及未分配原因:

1
2
# 筛选关键信息:索引名、分片号、主/副本、状态、未分配原因
GET _cat/shards?h=index,shard,prirep,state,unassigned.reason&v

输出示例:

分片情况

  • prirep=p 表示主分片,r 表示副本分片。
  • unassigned.reason=ALLOCATION_FAILED 说明主分片分配失败,导致副本也无法分配。

深入分析分配失败原因

使用 _cluster/allocation/explain 查看分片分配失败的详细日志:

1
GET _cluster/allocation/explain

响应示例(磁盘空间不足):

分配失败原因

关键原因:节点磁盘使用率达 90%,超过 Elasticsearch 默认的高水位阈值(85%),导致分片无法分配。

验证资源状态

针对上述磁盘空间问题,通过 _cat/allocation 确认节点磁盘使用情况:

1
GET _cat/allocation?v

输出示例:

1
2
3
shards disk.used disk.avail disk.total disk.percent host      ip        node
5 18gb 200mb 20gb 99 192.168.1.1 node-1
3 10gb 10gb 20gb 50 192.168.1.2 node-2

可见 node-1 磁盘仅剩 200MB,使用率达 99%,触发分配限制。

解决方案:针对性修复

1. 磁盘空间不足(最常见)

解决步骤

  • 清理空间:删除节点上的非必要文件(如日志、旧快照),释放至少 10% 以上的磁盘空间。

  • 临时调整阈值(紧急情况):

    1
    2
    3
    4
    5
    6
    7
    8
    # 临时降低高水位阈值(重启后失效)
    PUT _cluster/settings
    {
    "transient": {
    "cluster.routing.allocation.disk.watermark.high": "95%", # 高水位设为95%
    "cluster.routing.allocation.disk.watermark.flood_stage": "97%" # 洪水阶段设为97%
    }
    }
  • 长期优化:扩容磁盘,或配置索引生命周期管理(ILM)自动删除过期数据。

验证:空间释放后,Elasticsearch 会自动重试分配分片,可通过 GET _cat/shards 确认状态变为 STARTED

2. 其他常见问题的解决

(1)分片分配被人为禁用

若通过 cluster.routing.allocation.enable 禁用了分配,需重新开启:

1
2
3
4
5
6
PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.enable": "all" # 允许所有分片分配
}
}
(2)节点资源不足(内存 / CPU 超限)
  • 检查节点资源:GET _nodes/stats(查看 jvm.memprocess.cpu)。
  • 解决:重启节点释放资源,或扩容节点配置。
(3)索引数据损坏
  • 尝试恢复快照:若有快照,通过 _snapshot API 恢复索引。

  • 重建索引:若数据可重新同步,删除损坏索引后重新写入数据:

    1
    DELETE problem_index  # 谨慎操作!确保数据可恢复
(4)节点间版本不兼容
  • 确认所有节点版本一致(主分片无法分配到版本更低的节点)。
  • 解决:升级节点至统一版本。

预防措施:避免 Red 状态再次发生

  1. 监控磁盘空间:通过 Elasticsearch Monitor 或第三方工具(如 Prometheus + Grafana)监控磁盘使用率,设置阈值告警(如超过 80% 告警)。

  2. 合理配置副本:为每个主分片配置至少 1 个副本(number_of_replicas: 1),避免单点故障导致主分片丢失。

  3. 禁用自动创建索引:防止误写入导致大量小索引占用资源:

    1
    2
    3
    4
    5
    6
    PUT _cluster/settings
    {
    "persistent": {
    "action.auto_create_index": ".monitoring*,*" # 仅允许特定索引自动创建
    }
    }
  4. 定期备份:通过快照机制定期备份索引,确保数据可恢复。

  5. 配置分片分配重试:自动重试临时分配失败的分片:

    1
    2
    3
    4
    5
    6
    7
    PUT _cluster/settings
    {
    "transient": {
    "cluster.routing.allocation.node_concurrent_recoveries": 5, # 并发恢复数
    "indices.recovery.max_bytes_per_sec": "100mb" # 恢复速度
    }
    }

欢迎关注我的其它发布渠道