Easysearch、Elasticsearch 还是 Opensearch,是个问题
breakers

breakers

indices.breaker.request.limit熔断时的栈

Elasticsearchweizijun 回复了问题 • 6 人关注 • 6 个回复 • 7666 次浏览 • 2018-03-05 14:50 • 来自相关话题

又一次遇到这种问题,breakers.request内存溢出

Elasticsearchkennywu76 回复了问题 • 4 人关注 • 1 个回复 • 3286 次浏览 • 2017-08-04 10:42 • 来自相关话题

条新动态, 点击查看
kennywu76

kennywu76 回答了问题 • 2017-09-19 15:01 • 6 个回复 不感兴趣

indices.breaker.request.limit熔断时的栈

赞同来自:

@novia 
 
我看了下代码,ES里很多计算,包括terms aggregation,都是通过BigArrays这个工具类申请大数组来存放计算数据的。 不管申请什么类型数据(long,int,byte, etc..)的数组,都会在实际分配内存之前,调用ad... 显示全部 »
@novia 
 
我看了下代码,ES里很多计算,包括terms aggregation,都是通过BigArrays这个工具类申请大数组来存放计算数据的。 不管申请什么类型数据(long,int,byte, etc..)的数组,都会在实际分配内存之前,调用adjustBreaker()方法,将新申请数组的大小交给breaker service来判断是否应该熔断。  

1041
 
这个方法内部会调用
breaker.addEstimateBytesAndMaybeBreak, 传入新申请的数组字节大小,作为一个增量值delta计入总的request的总字节数里面,然后判断是否超过request breaker设置的上限。 如果超过则触发一个"<reused_arrays>"类型的异常,也就是你贴的日志里看到的错误信息:

1042
 
breaker service对于一个node来说是全局的,也就是说这个结点上所有申请的bigarray的内存消耗会进行累计。
 
另外这些申请的大数组,都是继承自AbstractArray这个抽象类,这个类是releasable的,其close()方法里会调用
bigArrays.adjustBreaker将释放的内存从breaker的记录里减去。

1048

 
因此breaker是以所有进行中的查询聚合生成持有的bigarrays占用的内存为基础,再将新的内存申请累加上去,判断是否应该触发熔断掉,从而尽量避免内存消耗过大导致结点挂掉。  
 
根据你描述的有一段时间一直熔断的特征,要么是当时一直有大内存消耗的聚合请求在进来,要么是有大聚合耗时非常长,导致申请的bigarrays长时间被占用没有释放,并且接近request breaker临界值,致使新进来的聚合不断的被熔断。重启就好了,可能只是因为释放掉了这些进行中的高消耗查询。
 
建议下次再遇到问题时,用hot threads api看一下,高消耗的线程在做什么。
 

PS.   我看的代码是5.6的, 不排除早期版本熔断存在一些不完善的地方。

indices.breaker.request.limit熔断时的栈

回复

Elasticsearchweizijun 回复了问题 • 6 人关注 • 6 个回复 • 7666 次浏览 • 2018-03-05 14:50 • 来自相关话题

又一次遇到这种问题,breakers.request内存溢出

回复

Elasticsearchkennywu76 回复了问题 • 4 人关注 • 1 个回复 • 3286 次浏览 • 2017-08-04 10:42 • 来自相关话题