ElasticSearch内存详解

On Heap&&Off Heap

    Elasticsearch内存分为on heap以及off heap两部分。Elasticsearch能控制的是On Heap内存部分,这部分由JVM管理;Off Heap由Lucene管理,负责缓存倒排索引数据空间(Segment Memory)。

On Heap

  • Indexing Buffer 索引写入缓冲区,用于存储新写入的文档,当其被填满时,缓冲区中的文档被写入磁盘中的 segments 中。节点上所有 shard 共享。这部分空间是可以通过GC被反复利用的。
    缓冲区默认大小:
     indices.memory.index_buffer_size: 10%

    如果缓冲区大小设置了百分比,则 indices.memory.min_index_buffer_size 用于这是最小值,默认为 48mb。indices.memory.max_index_buffer_size 用于最大大小,无默认值。
  • Node Query Cache (node级别的filter过滤器结果缓存),每个节点有一个,被所有 shard 共享,filter query查询结果要么是 yes 要么是no,不涉及 scores 的计算。使用LRU淘汰策略,内存无法被GC。
    集群中每个节点都要配置,默认为:
    indices.queries.cache.size:10%

    可以通过配置关闭该缓存

    "settings": {
        "index.queries.cache.enable": false
      }

     

  • Shard Request Cache (shard级别的query result缓存)每个shard一个,默认情况下该缓存只缓存request的结果size为0的查询。所以该缓存不会缓存hits,但却会缓存 hits.total, aggregations 和 suggestions。可以通过Clear cache API清除缓存。另外该缓存默认是关闭的,需要手动开启,可以使用下面配置开启该缓存:
"settings": {
    "index.requests.cache.enable": true
  }

       开启缓存后,我们需要在那些需要缓存的搜索请求上加上request_cache=true这个参数才能使我们的查询请求被缓存,语句如下(size=0也是缓存生效的必要条件):

curl 'localhost:9200/index_name/_search?request_cache=true' -d'
{
	"size": 0,
	"aggs": {
		"popular_colors": {
			"terms": {
				"field": "colors"
			}
		}
	}
}
'

      另外该缓存在shard没有新数据写入时会一直存在;当有新数据写入时,每次的refresh操作都会使旧的缓存数据失效。    

      该缓存使用LRU淘汰策略,内存无法被GC。默认最大为:

indices.requests.cache.size:1%

 

  • Field Data Cache (用于排序、聚合使用的字段的缓存,只针对analyzed的String类型的字段,其他类型字段的排序以及聚合使用doc_values)。因为构建字段数据缓存代价昂贵,所以建议有足够的内存来存储。
    Fielddata 是 延迟 加载。如果你从来没有聚合一个analyzed的字符串,就不会加载 fielddata 到内存中。如果没有足够的内存保存fielddata时,Elastisearch会不断地从磁盘加载数据到内存,并剔除掉旧的内存数据。剔除操作会造成严重的磁盘I/O,并且引发大量的GC,会严重影响Elastisearch的性能。

       该配置默认无内存上限,但是可以通过配置来设置占用的heap总量:

indices.fielddata.cache.size:30%

        但是建议配置该项的值,并将该项的值设置的小于断路器的值(indices.breaker.fielddata.limit,默认是60%JVM堆内存),当查询尝试加载更多数据到内存时会抛异常(以此来阻止JVM OOM发生)。

  • Segments Cache(segments FST数据的缓存,为了加速查询,FST 永驻堆内内存,无法被 GC 回收。该部分内存无法设置大小,长期占用 50% ~ 70% 的堆内存,只能通过delete index,close index以及force-merge index释放内存。

        解释下FST:

        ES 底层存储采用 Lucene(搜索引擎),写入时会根据原始数据的内容,分词,然后生成倒排索引。查询时,先通过  查询倒排索引找到数据地址(DocID)),再读取原始数据(行存数据、列存数据)。但由于 Lucene 会为原始数据中的每个词都生成倒排索引,数据量较大。所以倒排索引对应的倒排表被存放在磁盘上。这样如果每次查询都直接读取磁盘上的倒排表,再查询目标关键词,会有很多次磁盘 IO,严重影响查询性能。为了解磁盘 IO 问题,Lucene 引入排索引的二级索引 FST [Finite State Transducer] 。原理上可以理解为前缀树,加速查询。

Off Heap

       Lucene 中的 倒排索引 segments 存储在文件中,由Lucene管理,为提高访问速度,都会把它加载到内存中,从而提高 Lucene 性能。所以建议至少留系统一半内存给Lucene。

        解释下Segment Cache,Segment Memory以及Segment的定义与关系

 位置存储数据调用关系
Segment CacheHeapSegment的FST数据

Segment-->Segment Cache(加载)

Client-->Segment Cache(查询)

Segment MemoryOff Heap

通过Segment Cache的FST关联出Segment数据,

加载到Off Heap用于加速查询

Segment-->Segment Memory(加载)

Client-->Segment Memory(查询)

SegmentDisk原始的Lucene数据

Segment Cache-->Segment(查询)

Segment-->Segment Memory(查询加载)

Segment-->Segment Cache(持续加载)

index Buffer-->Segment(持续写入)

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Elasticsearch是一种分布式搜索和分析引擎,它需要大量的内存来支持其高效的搜索和数据分析功能。因此,在部署Elasticsearch时,正确配置内存分配是非常重要的。下面是关于Elasticsearch内存分配设置的详细解释。 1. 堆内存分配 Elasticsearch使用Java编写,因此它的内存分配主要是通过Java虚拟机(JVM)来控制的。其,堆内存Elasticsearch最重要的内存分配之一。堆内存用于存储Elasticsearch的数据缓存和搜索缓存。默认情况下,Elasticsearch会将堆内存的大小设置为1GB。但是,这可能不足以支持大型数据集和高流量负载。因此,建议将堆内存大小设置为物理内存的一半,最大不超过32GB。 可以通过在elasticsearch.yml文件添加以下行来修改堆内存大小: ``` -Xms4g -Xmx4g ``` 其,“-Xms”代表Elasticsearch的初始堆内存分配,“-Xmx”代表Elasticsearch的最大堆内存分配。在上面的示例,堆内存大小被设置为4GB。 2. 分片内存分配 Elasticsearch的数据分片也需要内存来存储和搜索数据。默认情况下,每个分片被分配256MB的内存。但是,对于大型数据集和高流量负载,可能需要更多的内存来支持分片。建议将每个分片的内存大小设置为物理内存的1/4到1/2。 可以通过在elasticsearch.yml文件添加以下行来修改每个分片的内存大小: ``` indices.memory.index_buffer_size: 50% ``` 在上面的示例,每个分片被分配了50%的索引缓冲区内存。 3. 非堆内存分配 除了堆内存和分片内存之外,Elasticsearch还需要非堆内存来存储其他数据结构,例如线程栈和JVM元数据。默认情况下,Elasticsearch会将非堆内存的大小设置为64MB。然而,对于高流量负载或大型数据集,可能需要更多的非堆内存。 可以通过在elasticsearch.yml文件添加以下行来修改非堆内存的大小: ``` -XX:MaxDirectMemorySize=10g ``` 在上面的示例,非堆内存被设置为10GB。 总之,正确配置Elasticsearch内存分配非常重要,因为它可以显着提高搜索和分析性能。建议根据实际情况调整堆内存、分片内存和非堆内存的大小,以满足特定的负载需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值