Elasticsearch分片均衡的情况下,还会出现热写造成的bulk reject?

2022-04-26 16:21:01 浏览数 (1)

说明

本文描述问题及解决方法同样适用于 腾讯云 Elasticsearch Service(ES)

  • 系统环境说明

Linux环境:CentOS Linux release 7.2 (Final)

Elasticsearch: 7.10.1

Java:1.8.0_181

  • 机器配置

机器数量:6

内存:64G

硬盘:2T

CPU核心数:32

背景

众所周知,当业务写入量很大的时候,如果索引分片分布得不均衡,大概率会发生bulk reject。这是由于分片设计不合理,没有均匀分布到所有节点,无法充分利用Elasticsearch分布式架构的特性,请求全部集中到了个别节点,压力无法分散,进而导致的写入拒绝。

问题

对于背景中介绍的场景,本文则不做过多介绍。这里我们关注的是另外一种情况:

当ES集群所有索引分片设计合理的前提下,分片分布很均衡,但是还是有个别节点发生了写入拒绝。这种问题就比较奇怪,需要深入排查一下。

通过业务监控到的失败率,结合写入拒绝率,可以确认判断业务失败是由bulk reject引起的。

问题原因

通过排查发现,reject全部集中在一个节点:

回溯历史队列情况,也发现只有个别节点容易超过write queue的最大值(1024):

所以这里我第一时间怀疑是业务有指定分片写入的行为,通过确认,发现6块分片只有1块有数据,果不其然:

然后通过进一步确认,发现每条数据都指定了routing。而routing的值全文只有一个,所以routing的不合理设计就是造成问题的罪魁祸首。

解决方案

改造业务改变routing逻辑为随机值,或者不指定routing写入,才能解决该问题。

上图为改造之后的CPU监控,可以看到效果还是很明显的。CPU使用率从9号业务改造之后,各节点之间表现得更加均匀,没再有明显的热点。

bulk reject从9号之后,也再也没有发生过,问题解决。

总结

业务指定routing进行写入,当routing设计不合理时,会出现大部分routing值都是重复的,会使所有请求都被转发到同一个节点,直接导致个别节点写入队列被打满、其他队列都很空闲的现象。所以,合理的分片设计固然重要,合理的routing设计也不能忽视,不然都会引起写入拒绝。

0 人点赞