为什么我的 Amazon Elasticsearch Service (Amazon ES) 域卡在“正在处理”状态?

上次更新日期:2020 年 8 月 21 日

在执行配置更改后,我的 Amazon Elasticsearch Service (Amazon ES) 域卡在“正在处理”状态。为什么我的域卡住了,我该如何操作才能避免这种情况的发生?

简短描述

您的 Amazon ES 域可能会因以下几个原因而卡在“正在处理”状态:

  • 集群节点故障
  • 节点分布不均
  • 分区重新分配(使用 index.routing.allocation.require 参数)
  • CPU 利用率高
  • JVM 内存压力(源自大型查询负载、磁盘问题、节点故障)
  • 卡滞快照

最佳实践是先检查分区数量和分区分配,然后再执行排查Amazon ES 域上的问题

有关分区重新分配和更新必需参数的更多信息,请参阅 Elasticsearch 网站上的索引级分区分配过滤。

解决方法

节点分布不均

Amazon ES 会在快照恢复、域配置更改、复制级别更改、节点故障和节点启动期间迁移分区。如果在蓝/绿部署期间,集群上的分区过多,则可能会减慢分区的迁移过程。高 CPU 利用率和高 JVM 内存压力也可能会减慢迁移过程,导致集群卡在“正在处理”状态。因此,如果没有足够的节点均匀地分布在多个分区上,则分区将变为“未分配”。有关蓝/绿部署的更多信息,请参阅配置更改

如果 Elasticsearch 集群卡在“正在处理”状态,请考虑减少集群中的分区数量。有关指定适当分区数的更多信息,请参阅选择分区数量

要确定分区是否正在迁移,请键入以下命令语法:

$ curl -XGET "ES_Endpoint/_cat/recovery?v&active_only"

注意:请先等待几分钟,然后再运行该命令。如果输出发生更改,则表明分区仍在迁移。

然后,检查分配给每个节点的分区数量和正在使用的磁盘空间量:

$ curl -XGET ES_Endpoint/_cat/allocation?v

注意:此命令语法还会指明集群节点是否因高磁盘使用率或 JVM 内存压力而发生故障。

未分配的分区

要检查集群中分区和索引的数量,请使用以下语法:

$ curl -XGET ES_Endpoint/_cat/indices
$ curl -XGET ES_Endpoint/_cat/shards

在确定未分配的分区之后,最大程度地减少域中不必要分区的数量。有关分区计算的更多信息,请参阅 Get started with Amazon Elasticsearch Service: How many shards do I need?

减少集群中的分区数

要减少集群中的分区数或任何开销,请删除所有旧的或过时的索引:

$ curl -XDELETE ES_Endpoint/oldindex1,oldindex2

如果配置了索引轮换,则每次轮换都将导致创建一组新的分区。默认情况下,Amazon ES 为每个索引创建五个主分区,为每个主分区创建一个副本分区。这种索引轮换最终可能会导致主节点过载。要避免过载并控制未来的分区增长,请考虑更改索引轮换策略或使用索引模板

注意:您只能在创建新索引或重新索引您的现有数据时指定分区数量。在索引文档之前,请选择分区数量

要指定新索引中的分区数量,请运行以下命令:

$ curl -XPUT ES_Endpoint/index-name -H 'Content-Type: application/ json' -d'
{
      "settings": {
            "index": {
                    "number_of_shards": 3,
                    "number_of_replicas": 1                   
       }        
}'

注意:Amazon ES 无法更改现有索引中主分区的数量。有关在 Amazon ES 中索引数据的更多信息,请参阅索引简介

要重建现有索引,请执行以下任务:

1.    创建并定义新的索引模板。以下语法可指定集群中新建分区的数量:

$ curl -XPUT ES_Endpoint/_template/template_1 -H 'Content-Type: application/json' -d'
{
      "index_patterns": ["*"],
      "settings": {
            "number_of_shards": 3,
            "number_of_replicas": 1     
      }
}'

2.    通过调用 _reindex API 操作重新索引(Amazon ES 版本 5.1 和更高版本)。以下语法可将您的数据移动到一个新索引,从而在索引模板中指定新的分区数量。

$ curl -XPOST ES_Endpoint/_reindex -H 'Content-Type: application/json' -d '
{
      "source": {   
            "index": "old_index"
      },
      "dest": {
            "index": "new_index"
      }   
}'

重要提示:如果您的访问策略包括 AWS Identity and Access Management (IAM) 用户或角色,您必须签署对 Amazon Elasticsearch Service API 的 HTTP 请求

3.    验证新索引和旧索引是否具有相同数量的文档:

$ curl -XGET ES_Endpoint/_cat/indices/old_index,new_index?v

4.    如果新索引和旧索引具有相同数量的文档,您可以随后删除旧索引:

$ curl -XDELETE ES_Endpoint/old_index

5.    重新运行您的配置更新。有关配置更改的更多信息,请参阅关于配置更改