红色或黄色集群健康状态编辑

红色或黄色集群健康状态表示一个或多个分片未分配到节点。

  • 红色健康状态: 集群中有一些未分配的主分片,这意味着某些操作(如搜索和索引)可能会失败。
  • 黄色健康状态: 集群中没有未分配的主分片,但有一些未分配的副本分片。这会增加数据丢失的风险,并可能降低集群性能。

当您的集群处于红色或黄色健康状态时,它将继续尽可能地处理搜索和索引,但可能会延迟某些管理和清理活动,直到集群恢复到绿色健康状态。例如,一些 ILM 操作要求它们操作的索引具有绿色健康状态。

在许多情况下,您的集群将自动恢复到绿色健康状态。如果集群没有自动恢复,那么您必须 手动解决 剩余问题,以便管理和清理活动可以继续进行。

诊断您的集群状态编辑

检查您的集群状态

使用 集群健康 API

response = client.cluster.health(
  filter_path: 'status,*_shards'
)
puts response
GET _cluster/health?filter_path=status,*_shards

一个健康的集群具有绿色的 status 和零个 unassigned_shards。黄色状态表示只有副本未分配。红色状态表示一个或多个主分片未分配。

查看未分配的分片

要查看未分配的分片,请使用 cat 分片 API

response = client.cat.shards(
  v: true,
  h: 'index,shard,prirep,state,node,unassigned.reason',
  s: 'state'
)
puts response
GET _cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state

未分配的分片具有 stateUNASSIGNEDprirep 值对于主分片为 p,对于副本为 r

要了解为什么未分配的分片没有被分配以及您必须采取什么措施才能让 Elasticsearch 分配它,请使用 集群分配解释 API

response = client.cluster.allocation_explain(
  filter_path: 'index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*',
  body: {
    index: 'my-index',
    shard: 0,
    primary: false
  }
)
puts response
GET _cluster/allocation/explain?filter_path=index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*
{
  "index": "my-index",
  "shard": 0,
  "primary": false
}

修复红色或黄色集群状态编辑

分片可能由于多种原因而变得未分配。以下提示概述了最常见的原因及其解决方案。

重新启用分片分配编辑

您通常会在 重启 或其他集群维护期间禁用分配。如果您忘记之后重新启用分配,Elasticsearch 将无法分配分片。要重新启用分配,请重置 cluster.routing.allocation.enable 集群设置。

response = client.cluster.put_settings(
  body: {
    persistent: {
      'cluster.routing.allocation.enable' => nil
    }
  }
)
puts response
PUT _cluster/settings
{
  "persistent" : {
    "cluster.routing.allocation.enable" : null
  }
}
恢复丢失的节点编辑

当数据节点离开集群时,分片通常会变得未分配。这可能由于多种原因发生,从连接问题到硬件故障。在您解决问题并恢复节点后,它将重新加入集群。Elasticsearch 然后将自动分配任何未分配的分片。

为了避免浪费资源在临时问题上,Elasticsearch 默认情况下延迟分配 一分钟。如果您已经恢复了节点并且不想等待延迟时间,您可以调用 集群重新路由 API,不带任何参数即可启动分配过程。该过程在后台异步运行。

response = client.cluster.reroute(
  metric: 'none'
)
puts response
POST _cluster/reroute?metric=none
修复分配设置编辑

配置错误的分配设置会导致主分片未分配。这些设置包括

要查看您的分配设置,请使用 获取索引设置集群获取设置 API。

response = client.indices.get_settings(
  index: 'my-index',
  flat_settings: true,
  include_defaults: true
)
puts response

response = client.cluster.get_settings(
  flat_settings: true,
  include_defaults: true
)
puts response
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 索引设置以减少每个主分片的副本数量。我们建议每个主分片至少保留一个副本。
response = client.indices.put_settings(
  body: {
    'index.number_of_replicas' => 1
  }
)
puts response
PUT _settings
{
  "index.number_of_replicas": 1
}
释放或增加磁盘空间编辑

Elasticsearch 使用 低磁盘水位线 来确保数据节点有足够的磁盘空间来容纳传入的分片。默认情况下,Elasticsearch 不会将分片分配到使用超过 85% 磁盘空间的节点。

要检查节点的当前磁盘空间,请使用 cat 分配 API

response = client.cat.allocation(
  v: true,
  h: 'node,shards,disk.*'
)
puts response
GET _cat/allocation?v=true&h=node,shards,disk.*

如果您的节点磁盘空间不足,您有以下几种选择

  • 升级您的节点以增加磁盘空间。
  • 删除不需要的索引以释放空间。如果您使用 ILM,您可以更新您的生命周期策略以使用 可搜索快照 或添加删除阶段。如果您不再需要搜索数据,您可以使用 快照 将其存储在集群之外。
  • 如果您不再写入索引,请使用 强制合并 API 或 ILM 的 强制合并操作 将其段合并成更大的段。

    response = client.indices.forcemerge(
      index: 'my-index'
    )
    puts response
    POST my-index/_forcemerge
  • 如果索引是只读的,请使用 缩减索引 API 或 ILM 的 缩减操作 来减少其主分片数量。

    response = client.indices.shrink(
      index: 'my-index',
      target: 'my-shrunken-index'
    )
    puts response
    POST my-index/_shrink/my-shrunken-index
  • 如果您的节点具有较大的磁盘容量,您可以增加低磁盘水位线或将其设置为明确的字节值。

    PUT _cluster/settings
    {
      "persistent": {
        "cluster.routing.allocation.disk.watermark.low": "30gb"
      }
    }
减少 JVM 内存压力编辑

分片分配需要 JVM 堆内存。高 JVM 内存压力会触发 断路器,阻止分配并将分片保持未分配状态。请参阅 高 JVM 内存压力

恢复丢失的主分片数据编辑

如果包含主分片的节点丢失,Elasticsearch 通常可以使用另一个节点上的副本替换它。如果您无法恢复节点并且副本不存在或无法恢复,您需要从 快照 或原始数据源重新添加丢失的数据。

仅当节点恢复不再可能时才使用此选项。此过程会分配一个空的主分片。如果该节点稍后重新加入集群,Elasticsearch 将使用来自此较新的空分片的数据覆盖其主分片,从而导致数据丢失。

使用 集群重新路由 API 手动将未分配的主分片分配到同一层中的另一个数据节点。将 accept_data_loss 设置为 true

POST _cluster/reroute?metric=none
{
  "commands": [
    {
      "allocate_empty_primary": {
        "index": "my-index",
        "shard": 0,
        "node": "my-node",
        "accept_data_loss": "true"
      }
    }
  ]
}

如果您将丢失的索引数据备份到快照,请使用 恢复快照 API 恢复单个索引。或者,您可以从原始数据源索引丢失的数据。