searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

ElasticSearch的缓存,你知道多少?

2023-04-28 10:34:13
148
0

ElasticSearch涉及的缓存,大致有4种。分别为,page cache、node-level query cache、shard-level request cache、field data cache。

page cache 查询过程中读取 Lucene 文件时会被操作系统 pagecache 缓存,pagecache使用类似 LRU 的策略对数据进行淘汰,但是由于 pagecache 对所有文件一视同仁,并且难以控制,此处也不做深入讨论。

field data cache 对于 text 类型进行聚合等获取字段值的行为时才会用到 fielddata,他会占用大量内存。fielddata默认关闭,因为在 text 类型上执行聚合一般是没有意义的,因此这里不深入讨论。

好了,接下来,我们重点介绍node-level query cache和shard-level request cache。

shard-level request cache

介绍:

是分片级别的查询缓存,每个分片有自己的缓存。该缓存采用 LRU 机制,缓存的 key 是整个客户端请求,缓存内容为单个分片的查询结果。如果一个客户端请求被数据节点缓存了,下次查询的时候可以直接从缓存获取,无需对分片进行查询。缓存的实现在 IndicesRequestCache 类中,缓存的 key 是一个复合结构,主要包括shard,indexreader,以及客户端请求三个信息。

注意,上面加黑的“客户端请求”五个字。官方blog中有一句解释,“This cache helps a lot in speeding Kibana up by caching search responses consisting only of aggregations”就是说此缓存可以加快我们再kibana的搜索,为什么是kibana中搜索呢?因为我们的大部分请求,可能来自同一个kibana。

 

缓存策略:

并非所有的分片级查询都会被缓存。

缓存策略指哪些类型的查询需要缓存,哪些类型的缓存无需缓存。IndicesService#canCache 方法中定义了某个请求是否可以被缓存,简单的可以理解成只有客户端查询请求中 size=0的情况下才会被缓存,其他不被缓存的条件还包括 scroll、设置了 profile属性,查询类型不是 QUERY_THEN_FETCH,以及设置了 requestCache=false等。另外一些存在不确定性的查询例如:范围查询带有now,由于它是毫秒级别的,缓存下来没有意义,类似的还有在脚本查询中使用了 Math.random() 等函数的查询也不会进行缓存。

查询结果中被缓存的内容主要包括:aggregations(聚合结果)、hits.total、以及 suggestions等。

由于 Request Cache 是分片级别的缓存,当有新的 segment 写入到分片后,缓存会失效,因为之前的缓存结果已经无法代表整个分片的查询结果。所以分片每次 refresh之后,缓存会被清除。

 

缓存设置:

indices.requests.cache.size:默认堆内存的1%

index.requests.cache.enable:是否开启缓存,默认开启

 

 

node-level query cache

介绍:

node-level query cache 是 Lucene 层面实现的,封装在 LRUQueryCache 类中,默认开启。一个ES的查询会先被parse 成一系列的Lucene 的phrase,这些phrases 中的filter语句,如果对于查询条件是一样的时候,其实结果集是已定的,那么这些phrase 其实就是可以存放在一个地方当做cache用,这个就是 query cache

 

缓存策略:

并非所有的 filter 查询都会被缓存下来。

QueryCache策略决定某个查询要不要缓存。ES 使用 UsageTrackingQueryCachingPolicy作为默认的缓存策略,在这个策略中,判断某个查询要不要缓存,主要关注两点:

某些类型的查询,永远不会缓存,目前 shouldNeverCache 方法中定义了以下类型:


某条 query 的 访问频率大于等于特定阈值之后,该 query结果才会被缓存。对于访问频率,主要分为2类,一类是访问2次就会被缓存,包括: MultiTermQuery、MultiTermQueryConstantScoreWrapper、TermInSetQuery、PointQuery 在 isCostly方法中定义。其余类型的查询访问5次会被缓存。
最近使用次数如何统计的?lucene 里维护一个大小为256的环形缓冲,最近使用过的 query 会做一下 hash 保存到这个缓冲里,当缓冲满的时候直接覆盖最后一个,被访问一次也不会调整他在缓冲里的顺序。因此“最近访问频率”可以理解成:在最近的256个历史记录里,query 被访问的次数。

 

缓存设置:

indices.queries.cache.count:默认缓存10000个子查询的结果

indices.queries.cache.size:缓存大小默认为堆内存的10%

 

 

参考: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

0条评论
0 / 1000
1****n
10文章数
0粉丝数
1****n
10 文章 | 0 粉丝
原创

ElasticSearch的缓存,你知道多少?

2023-04-28 10:34:13
148
0

ElasticSearch涉及的缓存,大致有4种。分别为,page cache、node-level query cache、shard-level request cache、field data cache。

page cache 查询过程中读取 Lucene 文件时会被操作系统 pagecache 缓存,pagecache使用类似 LRU 的策略对数据进行淘汰,但是由于 pagecache 对所有文件一视同仁,并且难以控制,此处也不做深入讨论。

field data cache 对于 text 类型进行聚合等获取字段值的行为时才会用到 fielddata,他会占用大量内存。fielddata默认关闭,因为在 text 类型上执行聚合一般是没有意义的,因此这里不深入讨论。

好了,接下来,我们重点介绍node-level query cache和shard-level request cache。

shard-level request cache

介绍:

是分片级别的查询缓存,每个分片有自己的缓存。该缓存采用 LRU 机制,缓存的 key 是整个客户端请求,缓存内容为单个分片的查询结果。如果一个客户端请求被数据节点缓存了,下次查询的时候可以直接从缓存获取,无需对分片进行查询。缓存的实现在 IndicesRequestCache 类中,缓存的 key 是一个复合结构,主要包括shard,indexreader,以及客户端请求三个信息。

注意,上面加黑的“客户端请求”五个字。官方blog中有一句解释,“This cache helps a lot in speeding Kibana up by caching search responses consisting only of aggregations”就是说此缓存可以加快我们再kibana的搜索,为什么是kibana中搜索呢?因为我们的大部分请求,可能来自同一个kibana。

 

缓存策略:

并非所有的分片级查询都会被缓存。

缓存策略指哪些类型的查询需要缓存,哪些类型的缓存无需缓存。IndicesService#canCache 方法中定义了某个请求是否可以被缓存,简单的可以理解成只有客户端查询请求中 size=0的情况下才会被缓存,其他不被缓存的条件还包括 scroll、设置了 profile属性,查询类型不是 QUERY_THEN_FETCH,以及设置了 requestCache=false等。另外一些存在不确定性的查询例如:范围查询带有now,由于它是毫秒级别的,缓存下来没有意义,类似的还有在脚本查询中使用了 Math.random() 等函数的查询也不会进行缓存。

查询结果中被缓存的内容主要包括:aggregations(聚合结果)、hits.total、以及 suggestions等。

由于 Request Cache 是分片级别的缓存,当有新的 segment 写入到分片后,缓存会失效,因为之前的缓存结果已经无法代表整个分片的查询结果。所以分片每次 refresh之后,缓存会被清除。

 

缓存设置:

indices.requests.cache.size:默认堆内存的1%

index.requests.cache.enable:是否开启缓存,默认开启

 

 

node-level query cache

介绍:

node-level query cache 是 Lucene 层面实现的,封装在 LRUQueryCache 类中,默认开启。一个ES的查询会先被parse 成一系列的Lucene 的phrase,这些phrases 中的filter语句,如果对于查询条件是一样的时候,其实结果集是已定的,那么这些phrase 其实就是可以存放在一个地方当做cache用,这个就是 query cache

 

缓存策略:

并非所有的 filter 查询都会被缓存下来。

QueryCache策略决定某个查询要不要缓存。ES 使用 UsageTrackingQueryCachingPolicy作为默认的缓存策略,在这个策略中,判断某个查询要不要缓存,主要关注两点:

某些类型的查询,永远不会缓存,目前 shouldNeverCache 方法中定义了以下类型:


某条 query 的 访问频率大于等于特定阈值之后,该 query结果才会被缓存。对于访问频率,主要分为2类,一类是访问2次就会被缓存,包括: MultiTermQuery、MultiTermQueryConstantScoreWrapper、TermInSetQuery、PointQuery 在 isCostly方法中定义。其余类型的查询访问5次会被缓存。
最近使用次数如何统计的?lucene 里维护一个大小为256的环形缓冲,最近使用过的 query 会做一下 hash 保存到这个缓冲里,当缓冲满的时候直接覆盖最后一个,被访问一次也不会调整他在缓冲里的顺序。因此“最近访问频率”可以理解成:在最近的256个历史记录里,query 被访问的次数。

 

缓存设置:

indices.queries.cache.count:默认缓存10000个子查询的结果

indices.queries.cache.size:缓存大小默认为堆内存的10%

 

 

参考: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

文章来自个人专栏
elasticsearch
10 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0