1. Node Query Cache
根据名称其实就能理解,这是属于Node级别的缓存。主要用于缓存Filter中的Query结果,基于LRU策略,当缓存满了的情况下,会自动去除一个最近最少被使用的Query Cache。
1.1. 缓存结构
缓存分为两个级别,第一级是Query
,第二级是Segmemt
,就像是Map<Query, Map<Segment, DocIdSet>>
这种结构一样。DocIdSet
使用的数据结构是Bitset
。
1.2. 重要参数介绍
indices.queries.cache.size
集群中的每个节点都必须有的静态配置,用来控制用来缓存的内存大小,默认是10%,支持两种格式一种是百分数,代表占节点heap的百分比,另一种则是精确的值,比如512mb。
indices.queries.cache.count
在官方文档并没有写,这是一个节点级别的配置,可以在elasticsearch.yml中配置,控制缓存的总数量。
indices.queries.cache.all_segments
用于是否在所有 Segment
上启用缓存,默认是false,不会对文档数小于100000或者小于整个索引大小的3%的Segment
进行缓存。
index.queries.cache.enabled
是属于index级别的配置,用来控制是否启用缓存,默认是开启的。
1.3. 什么样的Query会被缓存
- 对于
TermQuery
、MatchAllDocsQuery
等这种查询都不被缓存。当BooleanQuey
的字节点为空时不会被缓存,当Dis Max Query
的Disjuncts
为空时不会被缓存。 - 对于历史查询次数有要求,对于消耗高昂的Query只需要2次就加入缓存,其他的默认是5次,对于
BooleanQuery
和DisjunctionMaxQuery
次数为4次。默认的,这个历史查询的数量是256。
1.4. 什么样的segment会被缓存
Segment
中文档数大于100000或者大于整个所以大小的3%。
请注意如果想要索引所有段,请设置indices.queries.cache.all_segments
1.5. 新索引的文档,缓存会失效或者重新构建吗
缓存不会失效,而是通过判断文档是否符合Query
的条件,如果符合条件的话则会将文档加入到Bitset
中。
2. Field data Cache
主要用于sort
以及aggs
的字段。这会把字段的值加载到内存中,以便于快速访问。field data cache
的构建非常昂贵,因此最好能分配足够的内存以保障它能长时间处于被加载的状态。
一定要注意数据建模,对于不合理的字段启用
field data cache
代价非常大,而且性能特别差
indices.fielddata.cache.size
用来控制缓存的大小,支持两种格式,一种是百分数,代表占节点heap的百分比,另一种是精确值,如10gb,默认是无限。
3. Shard Request Cache
顾名思义,Shard级别的缓存。默认的主要用于缓存size=0的请求,aggs
和suggestions
,还有就是hits.total
。
需要注意,每当分片索引refresh的时候,如果数据发生了实际变化,那么缓存就会自动失效。所以呢,refresh时间越长,那么缓存的时间也就越长。缓存采用的也是LRU策略。
缓存是以请求的JSON为
Key
来进行存储的,那么也就是说,当同样含义的不同形式的请求将无法识别缓存。
3.1. 索引级别禁用缓存
index.requests.cache.enable
这个参数用来控制是否启用分片级别的缓存,默认是false
3.2. 请求时禁用缓存
通过url传参方式request_cache=true
3.3. 主要的缓存配置
indices.requests.cache.size
用来控制缓存在heap
中的大小,默认是1%。
4. Indexing Buffer
用于缓存新索引的数据,用于缓存新索引的数据,当空间填满之后,会将数据写到磁盘上成为一个新的段。