
breakers
indices.breaker.request.limit熔断时的栈
Elasticsearch • weizijun 回复了问题 • 6 人关注 • 6 个回复 • 7666 次浏览 • 2018-03-05 14:50
又一次遇到这种问题,breakers.request内存溢出
Elasticsearch • kennywu76 回复了问题 • 4 人关注 • 1 个回复 • 3286 次浏览 • 2017-08-04 10:42
@novia
我看了下代码,ES里很多计算,包括terms aggregation,都是通过BigArrays这个工具类申请大数组来存放计算数据的。 不管申请什么类型数据(long,int,byte, etc..)的数组,都会在实际分配内存之前,调用ad... 显示全部 »
我看了下代码,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的, 不排除早期版本熔断存在一些不完善的地方。
我看了下代码,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熔断时的栈
回复Elasticsearch • weizijun 回复了问题 • 6 人关注 • 6 个回复 • 7666 次浏览 • 2018-03-05 14:50
又一次遇到这种问题,breakers.request内存溢出
回复Elasticsearch • kennywu76 回复了问题 • 4 人关注 • 1 个回复 • 3286 次浏览 • 2017-08-04 10:42