03-limit-memory-usage-es控制聚合内存使用-elasticsearch权威指南翻译

前端之家收集整理的这篇文章主要介绍了03-limit-memory-usage-es控制聚合内存使用-elasticsearch权威指南翻译前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

为了让类似agg这种需要获取field value的操作是需要返回请求迅速的,这是为什么会把fielddata加载到内存中的原因,但是大量的fielddata会导致内存回收慢,甚至内存异常。

也许你惊奇的会发现es不仅把匹配你查询的文档的值放到了fielddata中,竟然把所有文档的值放在了内存中,甚至包括type。

逻辑是,你查询前面的可能会查询后面的,一次把所有数据加载进来并保存到内存中会很方便的和快速的,否则每个请求都去倒排索引中查一次。

JVM HEAP是有限制的,应该明智使用。有各种各样的机制来限制fielddata的使用,这些限制是非常重要的,因为滥用HEAP会导致系统不稳定甚至不可用。

选择一个HEAP SIZE

有两种规则来设置这个值,通过$ES_HEAP_SIZE变量

(1)不能超过系统内存的50%

(2)不能超过32GB,在32GB内,JVM会自动压缩,这样可以节约很多的内存,8bytes压缩到4 bytes,超过32,意味着你可用内存会越来越小,因为原来压缩的都变大了。

field data

indices.fielddata.cache.size 这个值控制了多少内存用于field data,当你进行查询的时候,需要新的field value,系统将会把数据加载dao内存而且尝试把数据加载到fielddata中,如果这些值超过了范围,其他的值将被踢出去来让出空间来。

默认es没有限制这个值,也就是说es从不会剔除数据去。

这个默认设置系统是有意这样做的,fielddata不是短暂数据,这些数据存在内存中能很快执行,而且建立这些数据是非常不容易的,如果每次请求再去加载这些数据表现会很差。

通过设置一个限定值将会根据值剔除数据,我们接下来会看到如何设置这个值。

首先,这个值是一个安全值,但不是内存不足的解决方案。

如果你没有足够的内存让这些数据常驻内存,es将会经常的从硬盘加载数据然后剔除旧的数据给新数据让出空间,evict过程会导致大量的IO操作,并且生成大量的内存垃圾需要去回收。

想象一下你正在index log数据,每天使用新的index,突然有天你想看前两天数据,如果是默认设置,旧数据酒会不断给内存中加入,直到circuit breaker。但这个时候系统也不能再加载新的数据了,因为都让fielddata占用了。

为了防止这件事情,需要在yml文件中进行设置:

indices.fielddata.cache.size: 40%

也可以设置一个具体的值:5gb

通过这个设置,上述那种情况中的新的fielddata会剔除出去,旧的会进来。

监控fielddata

对index监控

GET /_stats/fielddata?fields=*

对每个nodes监控

GET /_nodes/stats/indices/fielddata?fields=*

对每个index每个node监控

GET /_nodes/stats/indices/fielddata?level=indices&fields=*


circuit breaker(也许带入的fielddata 超过了整个的size)

细心的读者会发现一个问题:fielddata size是在数据加载进内存才核对的,如果一个query加入的fielddata比设置值大怎么办?结果是内存异常。

es有个circuit breaker就是用于处理这个问题的,这个模块会估计一个query进来带入的fielddata需要的内存,然后检察是否会超过fielddata的size

如果获取的值超过这个值,该query会在数据加载进来前被停止,也就是说不会看到内存异常.

默认这些值进行了设置:

indices.breaker.fielddata.limit 默认是HEAP的60%

indices.breaker.request.limit 默认是HEAP 40%

indices.breaker.total.limit 两者合起来不能超过HEAP 70%默认

可以动态的设置

PUT /_cluster/settings

{

"persistent" : {

"indices.breaker.fielddata.limit" : "40%"

}

}


circuit breaker limit 设置必须比indices.fielddata.cache.size大,如果小了,就不存在数据evict了,达到limit就阻止query了,cache第一道防线,limit最后一道防线。

最后这些值是保守值,用户还得好好思考啊

猜你在找的设计模式相关文章