Elasticsearch 之(32)fielddata内存控制、预加载以及circuit breaker断路器

本文深入探讨了 Elasticsearch 中 Fielddata 的核心原理,包括其 lazy 加载机制、内存限制及监控方法,并介绍了如何通过细粒度内存加载控制提升性能,同时覆盖了 Fielddata 预加载技术和 global ordinals 的应用,以及 circuitbreaker 机制防止内存溢出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

2、fielddata内存限制
elasticsearch.yml: indices.fielddata.cache.size: 20%,超出限制,清除内存已有fielddata数据
fielddata占用的内存超出了这个比例的限制,那么就清除掉内存中已有的fielddata数据
默认无限制,限制内存使用,但是会导致频繁evict和reload,大量IO性能损耗,以及内存碎片和gc

3、监控fielddata内存使用
GET /_stats/fielddata?fields=* //各个分片、索引的fielddata在内存中的占用情况
GET /_nodes/stats/indices/fielddata?fields=* //每个node的fielddata在内存中的占用情况
GET /_nodes/stats/indices/fielddata?level=indices&fields=* //每个node中的每个索引的fielddata在内存中的占用情况

4、fielddata filter的细粒度内存加载控制
POST /test_index/_mapping/my_type
{
  "properties": {
    "my_field": {
      "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就不加载


5、fielddata预加载
如果真的要对分词的field执行聚合,那么每次都在query-time现场生产fielddata并加载到内存中来,速度可能会比较慢我们是不是可以预先生成加载fielddata到内存中来???
POST /test_index/_mapping/test_type
{
  "properties": {
    "test_field": {
      "type": "string",
      "fielddata": {
        "loading" : "eager" 
      }
    }
  }
}
query-time的fielddata生成和加载到内存,变为index-time,建立倒排索引的时候,会同步生成fielddata并且加载到内存中来,这样的话,对分词field的聚合性能当然会大幅度增强序号标记预加载

global ordinal原理解释
doc1: status1
doc2: status2
doc3: status2
doc4: status1

有很多重复值的情况,会进行global ordinal标记
status1 --> 0
status2 --> 1
doc1: 0
doc2: 1
doc3: 1
doc4: 0

建立的fielddata也会是这个样子的,这样的好处就是减少重复字符串的出现的次数,减少内存的消耗

POST /test_index/_mapping/test_type
{
  "properties": {
    "test_field": {
      "type": "string",
      "fielddata": {
        "loading" : "eager_global_ordinals" 
      }
    }
  }
}

6、circuit breaker
如果一次query load的feilddata超过总内存,就会oom --> 内存溢出
circuit breaker会估算query要加载的fielddata大小,如果超出总内存,就短路,query直接失败
elasticsearch.yml
indices.breaker.fielddata.limit:fielddata的内存限制,默认60%
indices.breaker.request.limit:执行聚合的内存限制,默认40%
indices.breaker.total.limit:综合上面两个,限制在70%以内


转载于:https://www.cnblogs.com/wuzhiwei549/p/9113458.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值