Elasticsearch 集群状态变成黄色或者红色,怎么办?

Posted 铭毅天下Elasticsearch

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch 集群状态变成黄色或者红色,怎么办?相关的知识,希望对你有一定的参考价值。

已经基本包含了未分配的原因。但想得到更为详细的解释,需要使用如下的命令。

GET _cluster/allocation/explain?filter_path=index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*

  "index""order_info",
  "shard": 0,
  "primary"false

上面的几个参数解释如下:

  • index:索引名称,建议结合前一步指定。
  • shard:分片序号。从 0 开始计数。
  • primary:是否主分片;true 代表是;false 代表否。返回结果如下:
  • explanation 就是根本原因。如下 head 插件和 Kibana 都能看的更为明显。

    本质原因就是:只有一个节点,但是设置了副本,导致了主分片可以分片正常,副本分片无法分配。进而导致:集群健康状态是黄色。如何修复,下文会给出答案。

    4、修复非健康集群状态方案汇总

    分片变得未分配的原因有很多种。下文概述了最常见的原因及其解决方案。

    4.1 重新启用分片分配

    适用场景:节点重启过或者设置过禁用分片分配,但之后忘记设置重新分配策略,Elasticsearch 将无法分配分片。

    需要手动更新集群设置才可以实现重新分配。

    PUT _cluster/settings

      "persistent" : 
        "cluster.routing.allocation.enable" : null
      

    4.2 调整节点下线时分片分配控制策略

    当数据节点下线或特定原因宕机导致离开集群时,分片通常会变成未分配状态。造成这种情况的原因很多,比如:连接问题;比如:硬件故障问题等。

    当这些故障解决后,下线节点重新加入集群,然后,Elasaticsearch 将自动分配之前因节点下线等原因导致的未分配的分片。

    为了避免在上述问题上浪费资源,Elasticsearch 默认将分配延迟一分钟。根据业务实际需要,比如:因升级内存而下线数据节点的场景,可以将该延时值调大。

    参考命令行如下:

    PUT _all/_settings

      "settings"
        "index.unassigned.node_left.delayed_timeout""5m"
      

    如果已恢复节点并且不想等待延迟期,则可以调用不带参数的集群 reroute API 来启动分配过程。该进程在后台异步运行。

    POST _cluster/reroute
    4.3 分片分配设置层面修复

    分片分配设置错误可能会导致主分片无法分配。这些设置包括但不限于:

  • 索引层面的分片分配设置;

  • 集群层面的分片分配设置;

  • 集群层面的感知(awareness)分片分配设置。

  • 为了获取分片分配的细节设置,推荐使用如下两个 API:
    GET order_info/_settings?flat_settings=true&include_defaults=true

    GET _cluster/settings?flat_settings=true&include_defaults=true

    注意:

  • flat_settings 标志会影响设置列表的呈现。当 flat_settings 标志为 true 时,相关设置以平面格式返回,如上图所示。
  • include_defaults 默认值是 false,如果为 true,则代表返回集群所有缺省值。
  • 更多参数设置,推荐阅读:https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html

    https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-get-settings.html

    4.4 减少副本设置

    为了防止硬件故障,Elasticsearch 不会将副本分配给与其主分片相同的节点。

    如果没有其他数据节点可用于分配副本分片,则该副本分片保持未分配状态。如开篇截图的黄色集群状态,本质就是这个原因。要解决此问题,你可以:

  • 添加相同角色的数据节点。
  • 通过更新 index.number_of_replicas 索引设置减少每个主分片的副本数。
  • PS:为了保证集群线上业务的高可用性,建议每个主节点至少保留一个副本。

    如下是集群层面的设置,设置后对整个集群生效。

    PUT _settings

      "index.number_of_replicas": 0

    4.5  释放或增加磁盘空间

    Elasticsearch 使用 low disk watermark 低磁盘警戒水位线来确保数据节点有足够的磁盘空间来接收分片。

    默认情况下,Elasticsearch 不会将分片分配给磁盘使用率超过 85% 的节点。要检查节点的当前磁盘空间,请使用 cat allocation API。

    GET _cat/allocation?v=true&h=node,shards,disk.*

    如果你的节点磁盘空间不足,你通常有如下四个细化方案:

  • 方案 1:升级节点以增加磁盘空间。

  • 方案 2:删除不需要的索引以释放空间。

  • (1)如果你使用 ILM 索引生命周期管理,则可以更新生命周期策略以使用可搜索快照或添加删除阶段。

    (2)如果你不再需要搜索数据,可以使用快照将其历史数据存储在集群外。

    PS:这里强调的删除索引,delete 操作,不是删除数据的 delete_by_query 操作,切记!

  • 方案 3:如果你不再写入索引,请使用强制合并 API( force merge API ) 或 ILM 的强制合并操作将其段合并为更大的段。

  • POST order_info/_forcemerge
  • 方案 4:如果索引是只读的,请使用 shrink index API 或 ILM 的 shrink action 来减少其主分片数。
  • PUT order_index_ext

      "settings"
        "number_of_shards": 5,
        "number_of_replicas": 0
      


    POST order_index_ext/_bulk
    "index":"_id":1
    "title":"just testing..."
    "index":"_id":2
    "title":"just testing..."
    "index":"_id":3
    "title":"just testing..."

    PUT order_index_ext/_settings

      "index.blocks.write":"true"


    POST order_index_ext/_shrink/order_shrink_index
  • 方案 5:如果你的节点具有较大的磁盘容量,你可以调大低磁盘警戒水位线的值或将其设置为显式字节值。
  • 具体设置,参考如下:

    PUT _cluster/settings

      "persistent"
        "cluster.routing.allocation.disk.watermark.low""30gb"
      

    4.6 减少 JVM 堆内存压力

    分片分配需要 JVM 堆内存。高 JVM 内存压力可能会触发停止分片分配并使分片未分配的断路器(出现内存熔断现象)。

    推荐阅读:Elasticsearch JVM 堆内存使用率飙升,怎么办?

    4.7 主分片丢失情况的恢复策略

    如果包含主分片的节点因故障或其他原因下线,Elasticsearch 通常可以使用另一个节点上的副本替换它。

    如果包含主分片的节点无法恢复或其副本不存在或无法恢复(这是比较极端的情况),则需要从快照或原始数据源重新添加丢失的数据。

    注意啦,前方高能!!

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

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

    POST _cluster/reroute

      "commands": [
        
          "allocate_empty_primary"
            "index""order_info",
            "shard": 0,
            "node""node-1",
            "accept_data_loss""true"
          
        
      ]

    5、小结

    之前也有多篇文章介绍集群非健康状态修复,如下:

    干货 | Elasticsearch 集群健康值红色终极解决方案

    干货 | Elasticsearch集群黄色原因的终极探秘

    Elasticsearch 集群故障排查及修复指南

    本篇结合最新官方文档解读,更为全面和具体。

    实战环节如果遇到类似问题,建议参考本文,从上到下逐一排查,直至解决。

    你在实战环节肯定也遇到集群非健康状态问题,你是如何解决的呢?欢迎留言写下你的实战思考。

    参考

    1.  https://www.elastic.co/guide/en/elasticsearch/reference/current/fix-common-cluster-issues.html

    2.https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-get-settings.html


    推荐
    1、重磅 | 死磕 Elasticsearch 方法论认知清单(2021年国庆更新版)
    2如何从0到1打磨一门 Elasticsearch 线上直播课?(口碑不错)
    3、如何系统的学习 Elasticsearch ?
    4、Elasticsearch 中为什么会有大量文档插入后变成 deleted?

    短时间快习得多干货!

    和全球近 1600+ Elastic 爱好者一起精进!


    比同事抢先一步学习进阶干货

    ElasticSearch 集群与索引Red&Yellow状态分析思路

    参考技术A ES的索引有红,黄,绿三种状态,其中绿色代表正常状态,红色和黄色则说明多少有一些问题。我们在正常的ES运维过程中常常需要处理这些情况。

    先说明索引的三种颜色代表的意义吧:

    绿色:索引的所有分片都正常分配。

    黄色:至少有一个副本没有得到正确的分配。

    红色:至少有一个主分片没有得到正确的分配。

    集群和节点同样有三种颜色,这个颜色取决于相关索引的最差状况。比如说,整个集群中有3个节点,10个索引,每个索引分成3个分片,并有一份副本。如果其中有一个节点离线,上面有多个索引的主分片。那么集群的状态就是红色(red)

    事实上,索引状态变成红色或者黄色并不一定是出了问题。这些情况可以通过 cat API查询获知,参考文档: https://www.elastic.co/guide/en/elasticsearch/reference/7.1/cat-shards.html

    下面这些情况有可能是正常的情况,可能导致索引的状态临时性的变成红色和黄色。

    INDEX_CREATED : 集群正在创建索引。

    CLUSTER_RECOVERED : 集群处于重启阶段。

    INDEX_OPENED : 正在重新打开一个已经关闭的索引。

    NEW_INDEX_RESTORED :还原数据到一个新索引。

    EXISTING_INDEX_RESTORED : 还原数据到一个已经关闭的索引。

    REPLICA_ADDED : 索引的设置被修改,副本数增加。

    REROUTE_CANCELLED : 由于reroute命令被取消导致有一些分片没有被分配。

    REINITIALIZED :由于一个分片的状态重新退回到初始化导致。

    REALLOCATED_REPLICA :副本位置变化导致未分配。

    只有下面几个状态是明确地由于分片错误导致的:

    ALLOCATION_FAILED : 由于配置原因或者资源问题导致未分配情况。

    DANGLING_INDEX_IMPORTED : 副本在节点离线情况下被修改,在这个副本回到集群中时会产生此问题。

    在运维的过程中,如果发现集群的状态变成黄色或者红色,我们不妨等一等,很多问题会在短时间消失。然而,并不是所有错误都能自动修复,如果发现集群状态一直不正常的情况下,我们需要分析具体情况,找出导致问题的根本原因,再将其修复。

    ES提供了 health API供我们查询集群的状态和发现问题的原因:

    参考文档: https://www.elastic.co/guide/en/elasticsearch/reference/7.1/cluster-health.html

    我们可以看到一些用法:

    GET _cluster/health :检测集群的健康状态,可以使用这个API检测集群的节点数量

    GET _cluster/health?level=indices : 查看全部索引的状态,找出有问题的索引

    GET _cluster/health/index_name : 检测某个索引的状态,分析问题

    GET _cluster/health?level=shards : 查看分片分配的情况,寻找未分配的分片

    GET _cluster/allocation/explain : 查看第一个未分配分配的故障原因

    在找到原因后,需要对一些不能自动恢复的问题进行修复。

    比如,由于routing的设置,某些索引需要在标记为hot的节点上进行分配,但是集群内并没有标记为hot的节点,这时,索引就会由于主分片无法分配而处于红色状态。解决这种问题,可以向集群中添加或者将集群中某些节点标记为hot来解决,也可以改变routing的策略使得索引主分片可以被正确分配。

    又比如,如果当前集群只有一个节点,但是索引的副本配置并非是0,这时副本分片会由于没有多余的节点而无法分配。需要往集群中添加新节点或者将副本配置设为0。

    节点的磁盘空间不足可能导致相关分片无法分配,解决方法是增加新节点或者修改分片方案。

    上述有一个状态 DANGLING_INDEX_IMPORTED ,是由于节点离线后,其上的索引被修改导致,这种情况是无法自动恢复的。解决方法是删除该有问题的节点。

    集群中如果有节点离线,在相关分片重新分配之前,状态也会变为红色或者黄色。重新分配也也会加到集群剩余节点的压力。需要尽快修复问题,将节点重新上线。

    集群状态变成红色或者黄色是运维时经常会出现的状况,并不是所有的情况都是因为故障导致,一些正常的操作也会导致红色或者黄色的状况,并且会在一段时间之内自动恢复。由于故障导致的状态变化往往不会自动恢复,需要通过一些手段进行调查,寻找解决方案并修复问题。

    以上是关于Elasticsearch 集群状态变成黄色或者红色,怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

    Elasticsearch 集群状态变成黄色或者红色,怎么办?

    Elasticsearch:索引状态是红色还是黄色?为什么?

    ElasticSearch 集群与索引Red&Yellow状态分析思路

    Elasticsearch 有未分配的分片 详细思路

    elasticsearch 创建索引unassignedelasticsearch 创建索引后出现unassigned

    elasticsearch集群健康状态查看