fielddata内存控制

fielddata核心原理
  fielddata加载到内存的过程是lazy加载的,对一个analzyed field执行聚合时,才会加载,而且是field-level加载的.一个index的一个field,所有doc都会被加载,而不是少数doc,不是index-time创建,是query-time创建

fielddata内存限制
   indices.fielddata.cache.size: 20%,超出限制,清除内存已有fielddata数据
   fielddata占用的内存超出了这个比例的限制,那么就清除掉内存中已有的fielddata数据.

   indices.fielddata.cache.size 控制为 fielddata 分配的堆空间大小。 当你发起一个查询,分析字符串的聚合将会被加载到 fielddata,如果这些字符串之前没有被加载过。如果结果中 fielddata 大小超过了指定 大小 ,其他的值将会被回收从而获得空间

  默认情况下,设置都是 unbounded ,Elasticsearch 永远都不会从 fielddata 中回收数据。

indices.fielddata.cache.size:  20% 

  有了这个设置,最久未使用(LRU)的 fielddata 会被回收为新数据腾出空间。在 Fielddata的大小 中,我们提过关于给 fielddata 的大小加一个限制,从而确保旧的无用 fielddata 被回收的方法。 indices.fielddata.cache.size 和 indices.breaker.fielddata.limit 之间的关系非常重要。

监控fielddata内存使用

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

  如果一次query load的feilddata超过总内存,就会oom --> 内存溢出

  circuit breaker会估算query要加载的fielddata大小,如果超出总内存,就短路,query直接失败

indices.breaker.fielddata.limit:fielddata的内存限制,默认60%
indices.breaker.request.limit:执行聚合的内存限制,默认40%
indices.breaker.total.limit:综合上面两个,限制在70%以内

fielddata filter的细粒度内存加载控制

POST /test_index/_mapping
{
  "properties": {
      "type": "text",
      "fielddata": { 
        "filter": {
          "frequency": { 
            "min":              0.01, 
            "min_segment_size": 500  
          }
        }
      }
  }
}

  min:仅仅加载至少在1%的doc中出现过的term对应的fielddata

  比如说某个值,hello,总共有1000个doc,hello必须在10个doc中出现,那么这个hello对应的fielddata才会加载到内存中来

  min_segment_size:少于500 doc的segment不加载fielddata
  加载fielddata的时候,也是按照segment去进行加载的,某个segment里面的doc数量少于500个,那么这个segment的fielddata就不加载

 

 

posted on 2021-09-21 10:26  溪水静幽  阅读(471)  评论(0)    收藏  举报