Elasticsearch断路器相关知识及使用

背景 

在使用elasticsearch时,如果使用了高基数的聚合查询,有可能导致内存溢出OOM,导致elasticsearch的节点问题,进一步引发该节点上的分片漂移,从而影响线上的查询问题。 

原因 

Elasticsearch在执行高基数查询时,会默认为每组数据生成一个桶,并且存放在内存中,当基数很大也就是分组数据的重复性不高时,就会生成很多的桶,从而占用大量的内存。 

内存使用介绍 

ES的JVM heap按使用场景分为可GC部分和常驻部分。 可GC部分内存会随着GC操作而被回收; 常驻部分不会被GC,通常使用LRU策略来进行淘汰; 内存占用情况如下图: 

1.common space

包括了indexing buffer和其他ES运行需要的class。indexing buffer由indices.memory.index_buffer_size参数控制, 默认最大占用10%,当full up后,该部分数据被刷入磁盘对应的Segments中。这部分空间是可以被回收反复利用的。 

2.queryCache

node级别的filter过滤器结果缓存,大小由indices.queries.cache.size 参数控制,默认10%。使用LRU淘汰策略。 

3.requestCache

是shard级别的query result缓存,通常 only requests of size 0 such as aggregations, counts and suggestions will be cached。使用LRU淘汰策略。通过indices.requests.cache.size参数控制,默认1%。设置后整个NODE都生效。 

4.fieldDataCache

针对text字段,没有docValues属性(相当于列存储),当对text类型字段进行sort,agg时,需要将对应的字段内容全部加载到内存,这部分数据就放在fieldDataCache。通过indices.fielddata.cache.size 参数限制大小,默认不限制。这种情况下,占用内存会逐渐增多,直到触发熔断;新数据无法加载。 

5.segmentsMemory

缓存段信息,包括FST,Dimensional points for numeric range filters,Deleted documents bitset ,Doc values and stored fields codec formats等数据。这部分缓存是必须的,不能进行大小设置,通常跟index息息相关,close index、force merge均会释放部分空间。 

断路器介绍及设置 

ES通过断路器的设置,来保护集群内存不超过设定值,从而保证集群的稳定性。 

1.indices.breaker.fielddata.limit 

fielddata断路器默认设置堆的 40% 作为 fielddata 大小的上限。

2.indices.breaker.request.limit

request断路器估算需要完成其他请求部分的结构大小,例如创建一个聚合桶,默认限制是堆内存的 60%。它实际上是node level的一个统计值,统计的是这个结点上,各类查询聚合操作,需要申请的Bigarray的空间大小总和。 所以如果有一个聚合需要很大的空间,同时在执行的聚合可能也会被break掉。 

3.indices.breaker.total.limit 

父断路器,保证inflight、request(agg)和fielddata的使用不会使用超过堆内存的限制,默认70%。 

4.network.breaker.inflight requests.limit 

限制当前通过HTTP等进来的请求使用内存不能超过Node内存的指定值。这个内存主要是限制请求内容的长度。 默认100%。 

5.script.context.$CONTEXT.max_compilations_rate

特定时间间隔内允许为给定上下文编译的唯一动态脚本数的限制。默认为75/5m,即每5分钟75次。 

6.设置命令举例: 

{
  'error': {
    'type': 'circuit_breaking_exception',
    'reason': '[parent] Data too large, data for [<http_request>] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]',
    'bytes_wanted': 123848638,
    'bytes_limit': 123273216,
    'durability': 'TRANSIENT'
  },
  'status': 429
}

效果演示 

测试节点配置128MB的JVM运行,父熔断器设置为95%,即JVM使用达到117.5MB会触发熔断。然后不停的发出聚合请求,节点将返回code 429,如下: 

{
  'error': {
    'type': 'circuit_breaking_exception',
    'reason': '[parent] Data too large, data for [<http_request>] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]',
    'bytes_wanted': 123848638,
    'bytes_limit': 123273216,
    'durability': 'TRANSIENT'
  },
  'status': 429
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝-琪琪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值