1. 背景
在使用ES进行查询的时候,往往可以发现同一条query,查询多次后,越来越快直至1,2毫秒,聪明的你肯定一下就联想到,这肯定是缓存了查询结果到内存。
通过查询官方文档,可以看到有3个小章节描述缓存:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-cache.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/shard-request-cache.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-fielddata.html
以及1个小章节描述如何清理缓存:
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-clearcache.html
PS:分片中数据发生改变的时候,缓存自动失效
通过
GET /_stats/query_cache(request_cache,fielddata)?human
或者
GET /_nodes/stats/indices/query_cache(request_cache,fielddata)?human
查看各种类型缓存
2. 归纳
结合上述内容,我们可以总结出ES/Lucene内存使用情况:
ES使用堆内存情况:JVM堆内存
1、Indexing Buffer:索引缓冲区,用于存储新索引的文档,当其被填满时,缓存区中的文档被写入磁盘中的segments中。节点上所有shard共享
2、Node Query Cache:也称Filter Cache,对一个查询中包含的过滤器执行结果进行缓存,例如term、terms、range过滤器。每个节点都有一个,被所有shard共享
3、Shard Request Cache:缓存查询中参数size=0的请求,所以就不会缓存hits 而是缓存 hits.total,aggregations和suggestions
4、fielddata Cache:针对text类型(分词字符串类型)字段构建的正排索引,用于sort、aggregation查询,加载Fielddata Cache是一个非常昂贵的操作,一旦Fielddata被加载到内存,那么在该Fielddata Cache对应的Segement生命周期范围内都会驻留在内存中。也就是说当段合并时会触发合并后更大段的Fielddata Cache加载。
Lucene使用非堆内存情况:操作系统OS内存,缓存磁盘数据
1、Segments:段,最小的索引单元,不可变,存储在磁盘中,操作系统OS会把这些段文件缓存起来,以便更快的访问
2、Doc values:针对非text类型字段构建的正排索引,是在索引时与倒排索引同时生成。也就是说 Doc Values 和倒排索引一样,基于Segement生成并且是不可变的。用于sort、aggregation查询,存储在磁盘中,当 working set 远小于系统的可用内存,系统会自动将 Doc Values 驻留在内存中,使得其读写十分快速;不过,当其远大于可用内存时,系统会根据需要从磁盘读取 Doc Values,然后选择性放到分页缓存中。
来源:oschina
链接:https://my.oschina.net/KasuganoShin/blog/4412786