居然是你

ES集群,进行大量删除操作时候,bulk队列溢出

Elasticsearch | 作者 sk1234sk | 发布于2017年10月22日 | 阅读数:10063

背景:
一个es集群,版本5.4.0,由于存量数据比较多,需要进行删除。
因为需要对数据进行筛选,所有使用了单个delete接口。
使用javaApi,组装prepareDelete请求。

问题:
大量请求时候,会报错:
EsRejectedExecutionException: rejected execution ( bulk queue capacity 200)
这个很奇怪,因为在发送的是delete请求,报错也应该是index queue报错才对啊。

自己进行了测试:
搭建了一个集群,手动发送请求:
put 127.0.0.1:9200/blog/artile/2
delete 127.0.0.1:9200/blog/artile/2
看节点统计,"bulk": {
"threads": 4,
"queue": 0,
"active": 0,
"rejected": 0,
"largest": 2,
"completed": 2
},
index是0。

所以很奇怪,这种index或者delete不是应该走index队列吗? 为什么是bulk队列统计增加了? 是我的配置或者使用有问题吗?
请大家指点迷津啊
已邀请:
我在5.6版本上试了一下,的确如你所说,index/delete走的是bulk thread pool,看来是踩到坑了。 
 
拔了一下代码,delete操作是由TransportDeleteAction这个类来完成的,其实例化的过程中,指定的thread_pool的确是ThreadPool.Names.INDEX。 所以我也比较疑惑,为什么实际上用的是bulk thread pool。 多亏一个同事帮忙看了一下,才恍然大悟,这个类继承自TransportSingleItemBulkWriteAction类
test.jpg

 
而这个类的doExecute方法里,将请求的执行代理给了TransportBulkAction,进一步又代理给了TransportShardBulkAction。
test1.jpg

而这个类里是指定了bulk thread pool来执行操作请求。
 
indexAction也是同样的,被转变成了bulk action。
 
所以,问题就在于最新版本的ES,将index/delete操作转变成了只包含一条文档的bulk请求。 至于为什么要这样,也是同事帮我找到了github上的变更记录:
https://github.com/elastic/ela ... 21964
 
简而言之,官方测试发现一条记录的bulk和作为单条请求处理,底层操作性能开销几乎没有分别。 为了减少代码路径,做了这个操作的合并。 
 
这个变更是从ES 5.3开始的,之前的版本应该没有这个问题。
 
但是这个看起来埋了个小坑,因为index/delete/bulk现在共享bulk的线程池了,默认的线程池设置可能不够用。
 

要回复问题请先登录注册