Elasticsearch 缓存机制

1. 节点查询缓存(Node Query Cache)

官方文档简介

查询缓存负责缓存查询的结果。每个节点有一个查询缓存,由所有分片共享。缓存执行LRU回收策略:当缓存满时,将回收最近最少使用的数据,为新数据让路。无法查看正在缓存的内容。

查询缓存只缓存在filter上下文中使用的查询。

详细介绍

缓存数据结构

缓存分为两个级别,分别为QuerySegment,所以使用的数据结构是一个Map<Query, Map<Segment, DocIdSet>>DocIdSet则使用的是BitSet

参数说明

indices.queries.cache.size: 控制Filter缓存的内存大小,默认为10%。接受百分比值(如5%)或精确值(如512mb)。

indices.queries.cache.count: 在官方文档并没有写,这是一个节点级别的配置,可以在elasticsearch.yml中配置,控制缓存的总数量。如果缓存文档数量达到了该值,即使缓存大小还没有达到上限,也没有办法再利用了。值得注意的是,如果一个查询在本节点涉及到多个Segment,那么实际的cache_size将会是本值与Segment数量的乘积。

indices.queries.cache.all_segments: 用于是否在所有Segment上启用缓存,默认是false,不会对文档数小于100000并且小于整个索引大小的3%的Segment进行缓存。

index.queries.cache.enabled: 控制是否启用查询缓存。接受true(默认值)或false

可以被缓存的查询语句要求
  • 对于TermQueryMatchAllDocsQuery等这种查询都不被缓存。当BooleanQuey的字节点为空时不会被缓存,当Dis Max QueryDisjuncts为空时不会被缓存。

  • 对于历史查询次数有要求,对于消耗高昂的Query只需要2次就加入缓存,其他的默认是5次,对于BooleanQueryDisjunctionMaxQuery次数为4次。

什么样的Segment会被缓存

Segment中文档数大于100000或者大于整个所以大小的3%。如果想要索引所有段,可以设置indices.queries.cache.all_segments

新索引的文档,缓存会失效或者重新构建吗

缓存不会失效,而是通过判断文档是否符合Query的条件,如果符合条件的话则会将文档加入到BitSet中。

案例

查看ES查询缓冲情况

curl 'http://es.zjw.cn:9200/_stats/query_cache?pretty&human'

返回结果query_cache部分

"query_cache": {
  "memory_size": "2.5gb",
  "memory_size_in_bytes": 2690321531,
  "total_count": 83881663356,
  "hit_count": 37834074368,
  "miss_count": 46047588988,
  "cache_size": 118427,
  "cache_count": 42784311,
  "evictions": 42665884
}

从当前的query_cache看,evictionscache_size的360倍,说明cache_size过小,导致缓存倍频繁淘汰,导致缓存命中比例较小,可以适当调大indices.queries.cache.size大小和indices.queries.cache.count

2. 字段数据缓存(Field data Cache)

主要用于sort以及aggs的字段。这会把字段的值加载到内存中,以便于快速访问。field data cache的构建非常昂贵,因此最好能分配足够的内存以保障它能长时间处于被加载的状态。或者在创建索引时预见到某字段会被用于排序和聚合,而设置文档值,避免使用field data cache

一定要注意数据建模,对于不合理的字段启用field data cache代价非常大,而且性能特别差!

indices.fielddata.cache.size: 用来控制缓存的大小,支持两种格式,一种是百分数(代表占节点heap的百分比),另一种是精确值(如10gb),默认是无限。

3. 分片请求缓存(Shard Request Cache)

Shard级别的缓存。默认的主要用于缓存size=0的请求(aggssuggestions,还有就是hits.total)。

每当分片索引refresh的时候,如果数据发生了实际变化,那么缓存就会自动失效。所以refresh时间越长,那么缓存的时间也就越长。缓存采用的也是LRU淘汰策略。

缓存是以请求的JSONKey来进行存储的,那么也就是说,当同样含义的不同形式的请求将无法识别缓存。

索引级别禁用缓存

index.requests.cache.enable: 这个参数用来控制是否启用分片级别的缓存,默认是false

请求时禁用缓存

通过url传参方式request_cache=false

主要的缓存配置

indices.requests.cache.size 用来控制缓存在heap中的大小,默认是1%

4. 索引缓存(Indexing Buffer)

用于缓存新索引的数据,用于缓存新索引的数据,当空间填满之后,会将数据写到磁盘上成为一个新的段。它被划分为节点上的所有分片。以下设置为静态设置,必须在集群中的每个数据节点上配置:

indices.memory.index_buffer_size: 接受百分比或字节大小值。默认值为10%,这意味着分配给节点的堆总量的10%将被用作跨所有分片共享的索引缓冲区大小。

indices.memory.min_index_buffer_size: 如果index_buffer_size被指定为一个百分比,那么这个设置可以用来指定一个绝对的最小值。默认为48mb

indices.memory.max_index_buffer_size: 如果index_buffer_size被指定为一个百分比,那么这个设置可以用来指定一个绝对最大值。默认为无限。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值