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分配不均,具体可通过以下方法进行定位分析。
- 检查分片(shard)数据量是否过大。
单个分片数据量过大,可能引起Bulk Reject,建议单个分片大小控制在20GB - 50GB左右。可在kibana控制台,通过如下命令查看索引各个分片的大小。
GET _cat/shards?index=index_name&v
- 检查分片数是否分布不均匀。
- 通过CSS控制台集群详情页的“集群监控”中的“节点状态”查看,具体操作可参见查看监控指标。
- 通过CURL客户端,查看集群各个节点的分片个数。
curl "$p:$port/_cat/shards?index={index_name}&s=node,store:desc" | awk '{print $8}' | sort | uniq -c | sort
结果如下图所示:
第一列为分片个数,第二列为节点ID,有的节点分片为1,有的为8,分布极不均匀。
- 如果问题是由分片数分布不均匀导致。
- 可以通过如下命令设置“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)。
- 索引产生前设置。
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": {} }
- 可以通过如下命令设置“routing.allocation.total_shards_per_node”参数,动态调整某个index解决。