文档首页> 云搜索服务 CSS> 故障排除> 访问集群类> Elasticsearch集群出现写入拒绝“Bulk Reject”,如何解决?
更新时间:2023-09-11 GMT+08:00

Elasticsearch集群出现写入拒绝“Bulk Reject”,如何解决?

问题现象

集群在某些情况下会出现写入拒绝率增大“bulk reject”的现象,具体表现为bulk写入时,会有类似以下报错:

[2019-03-01 10:09:58][ERROR]rspItemError: {
    "reason": "rejected execution of org.elasticsearch.transport.TransportService$7@5436e129 on EsThreadPoolExecutor[bulk, queue capacity = 1024, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@6bd77359[Running, pool size = 12, active threads = 12, queued tasks = 2390, completed tasks = 20018208656]]",
    "type": "es_rejected_execution_exception"
}

问题分析

引起bulk reject的大多原因是shard容量过大或shard分配不均,具体可通过以下方法进行定位分析。

  1. 检查分片(shard)数据量是否过大。

    单个分片数据量过大,可能引起 Bulk Reject,建议单个分片大小控制在20GB - 50GB左右。可在kibana控制台,通过如下命令查看索引各个分片的大小。

    GET _cat/shards?index=index_name&v
  2. 检查分片数是否分布不均匀。

    提供如下两种方式查看:

    1. 通过CSS控制台集群详情页的“集群监控”中的“节点状态”查看,具体操作可参见查看监控指标
    2. 通过CURL客户端,查看集群各个节点的分片个数。
      curl "$p:$port/_cat/shards?index={index_name}&s=node,store:desc" | awk '{print $8}' | sort | uniq -c | sort

      结果如下图所示:

      第一列为分片个数,第二列为节点 ID,有的节点分片为1,有的为8,分布极不均匀。

解决方案

  • 如果问题是由分片数据量过大导致。

    分片大小可以通过index模版下的“number_of_shards”参数进行配置。

    模板创建完成后,再次新创建索引时生效,旧的索引不能调整。

  • 如果问题是由分片数分布不均匀导致。

    临时解决方案:

    1. 可以通过如下命令设置“routing.allocation.total_shards_per_node”参数,动态调整某个index解决。
      PUT <index_name>/_settings
      {
          "settings": {
              "index": {
                  "routing": {
                      "allocation": {
                          "total_shards_per_node": "3"
                      }
                  }
              }
          }
      }

      “total_shards_per_node”要留有一定的buffer,防止机器故障导致分片无法分配(例如10台机器,索引有20个分片,则 total_shards_per_node设置要大于2,可以取3)。

    2. 索引产生前设置。

      通过索引模板,设置其在每个节点上的分片个数。

      PUT _template/<template_name>
      {
          "order": 0,
          "template": "{index_prefix@}*",  //要调整的index前缀
          "settings": {
              "index": {
                  "number_of_shards": "30", //指定index分配的shard数,可以根据一个shard 30GB左右的空间来分配
                  "routing.allocation.total_shards_per_node": 3 //指定一个节点最多容纳的shards数
              }
          },
          "aliases": {}
      }