Elasticsearch filter context 的使用原理

news/2024/12/26 13:46:23/

ES querycache 加速匹配的方法

前言

ES 进行信息检索的时候,boolean 查询组合条件有 must/must_not/should/filter 四个操作。其中 must 和 filter 的用途都是用于过滤必要符合的条件,但是 filter 在查询过程中不算分并且可以进行缓存,这样逻辑简单又可以加速的查询方式经常得到 Elastic 的提倡。

可是,只有 filter 的条件可以被缓存么?这里的缓存是属于哪一部分?缓存有什么样的进入和淘汰机制?怎么去监控缓存的使用情况?

这些问题也会伴随着对 ES 的深入使用自然而然的产生。本文中,我们结合 Elastic 的一些资料进行探索。

什么是 Filter Context

仔细去看 Elastic 的文档可以发现,在 filter 的使用介绍里是这么写的Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.这里不仅措辞严谨的说 filter 条件以 filter context 的方式执行,并做了超链解释。

简而言之,filter context 主要用于查询的过滤条件,并且不用算分,与 bool 的 filter 条件没有严格关联,除了 bool 的 filter 外,bool 中的 must_not, constant_score 查询中的 filter,聚合中的 filter 也都属于。

如何进入 Query Cache

现在我们来看看是查询是怎么进入 Query Cache 的:

  1. 找到匹配文档

    在倒排索引中找到 filter 条件符合的词项,并在所有的文档中检索这个词项。

  2. 建立一个位图 bitset

    建立一个只包含 1 和 0 的位图 bitset,这个 bitset 用于描述所有文档的匹配情况,匹配的文档被设置为 1。ES 实际执行时,使用的是 RoaringBitMap

  3. 迭代 bitset

    一旦为某个查询生成了 bitset, Elasticsearch 就会遍历 bitset 以查找满足所有过滤条件的匹配文档集。执行顺序通常是首先迭代最稀疏的 bitset(因为它排除了最多数量的文档)。

  4. 增加使用计数

    把查询条件和其结果的 bitset 组合作为 key-value 进行缓存,这里利用对查询条件的使用记录来判断是否进缓存。简单来说,如果一个查询在最近的 256 个查询中被多次使用,它将被缓存在内存中。更为详细的保留机制见下一节。

Query Cache 的缓存机制

总体来说,Query Cache 是 Lucene 层面实现的,ES 层面会进行一些策略控制和信息统计。

Query Cache 会维护在相对较大的 segment 上,对于**存储小于 1w 文档数 或者 size 大小小于整体索引 size 3%**的 segment 不会维护 Query Cache(小 segment 本身的查询就比较快,不需要 cache 加速)。
docs_count(segment) < 10000 || segment.size < 3%*index.size

其管理策略类是 lucene 的 UsageTrackingQueryCachingPolicy,符合 LRU 的规则,也就是说 Query Cache 中的查询结果长时间不被访问会被优先淘汰。这里判断是否被缓存的方法是shouldCache(Query query)有兴趣的同学可以去研究下

判断是否可以缓存的主要规则如下:

  1. 判断是否为 filter 查询assert query instanceof BoostQuery == false;
  2. 命中永不缓存 shouldNeverCache 条件的淘汰,其中包括:TermQuery、MatchAllDocsQuery、MatchNoDocsQuery、以及子查询为空的 BooleanQuery、DisjunctionMaxQuery
  3. 某些大于特定阈值的查询可以被缓存:
    3.1 大于 2 次:MultiTermQuery、MultiTermQueryConstantScoreWrapper、TermInSetQuery、PointQuery(在 isCostly 方法中定义)
    3.2 大于 5 次:除了上面列出条件的所有 filter 查询

使用和观测 Query Cache

最后,我们来看下怎么去使用和观测 Query Cache。

默认情况下节点的 Query cache 最多缓存 10000 个子查询的结果,或者最多使用堆内存的 10%,都可以通过配置来调整:

indices.queries.cache.count  #默认 10000
indices.queries.cache.size   #默认 10%

对 Query Cache 也可以进行人工清理:POST /<index>/_cache/clear?query=true

而 Nodes stats API 和 Index stats API 都提供了 Query Cache 的监控

"query_cache": {"memory_size_in_bytes": 1110305640,//使用的size"total_count": 45109997,//历史查询总条数 total=hit+miss"hit_count": 1192144,//命中的"miss_count": 43917853,//未命中的"cache_size": 1309,//当前缓存的条数"cache_count": 51509,//历史缓存总条数"evictions": 50200//被驱逐的条数
}

使用小建议:

  1. 当 evictions 大量发生时,缓存被大量置换,对高敏感的业务可能会有一定的查询抖动。
  2. 在监控项上添加一个 hit/total 的百分比监控,更加直观。

小结

本文短暂总结了 Filter context 如何形成 Query Cache 并进行维护观测的整体流程。

其中对 Query Cache 和其他缓存有兴趣的同学可以研读张超老师的扒一扒缓存的裤子

Filter context 本身可以省去复杂的算分过程,再加上 Query Cache 的加速优势,建议大家在编写只需要匹配过滤查询语句中优先选择。

作者:金多安,极限科技搜索运维专家,Elastic 认证专家,搜索客社区日报责任编辑。一直从事与搜索运维相关的工作,日常会去挖掘 ES / Lucene 方向的搜索技术原理,保持搜索相关技术发展的关注。
原文:https://infinilabs.cn/blog/2024/elasticsearch-filter-context/


http://www.ppmy.cn/news/1558279.html

相关文章

分布式调度框架学习笔记

一、分布式调度框架的基本设计 二、线程池线程数量设置的基本逻辑 cpu是分时复用的方法&#xff0c;线程是cpu调度的最小单元 如果当前cpu核数是n&#xff0c;计算密集型线程数一般设为n&#xff0c;io密集型(包括磁盘io和网络io)线程数一般设置为2n. 计算密集型线程数一般设…

光谱相机的工作原理

光谱相机的工作原理主要基于不同物质对不同波长光的吸收、反射和透射特性存在差异&#xff0c;以下是其具体工作过程&#xff1a; 一、光的收集 目标物体在光源照射下&#xff0c;其表面会对光产生吸收、反射和透射等相互作用。光谱相机的光学系统&#xff08;如透镜、反射镜…

瑞吉外卖项目学习笔记(九)套餐列表分页查询、新增套餐、图片上传和下载

瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现 瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现 瑞吉外卖项目学习笔记(三)过滤器实现登录校验、添加员工、分页查询员工信息 瑞吉外卖项目学习笔记(四)TableField(fill FieldFill.INSERT)公共字…

【NLP 18、新词发现和TF·IDF】

目录 一、新词发现 1.新词发现的衡量标准 ① 内部稳固 ② 外部多变 2.示例 ① 初始化类 NewWordDetect ② 加载语料信息&#xff0c;并进行统计 ③ 统计指定长度的词频及其左右邻居字符词频 ④ 计算熵 ⑤ 计算左右熵 ​编辑 ⑥ 统计词长总数 ⑦ 计算互信息 ⑧ 计算每个词…

网络安全 | 云计算中的数据加密与访问控制

网络安全 | 云计算中的数据加密与访问控制 一、前言二、云计算概述2.1 云计算的定义与特点2.2 云计算的服务模式2.3 云计算的数据安全挑战 三、数据加密技术在云计算中的应用3.1 对称加密算法3.2 非对称加密算法3.3 混合加密算法 四、云计算中的访问控制模型4.1 基于角色的访问…

datatables快速入门

官网 进入官网https://datatables.net/ 点击下载 支持多种方式下载 快速入门 这里以cdn的方式演示 https://cdn.datatables.net/ <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport&…

Adobe Illustrator 中裁剪图像的最快方案

1. 置入图像&#xff1a;选择“文件 > 置入”&#xff0c;然后选择要裁剪的图像的PDF并单击“置入”。可以得到下面图中所示&#xff1a; 2. 选择右边工具栏中的矩形&#xff0c;新建一个矩形将你想要裁剪的地方覆盖住。下图中白色矩形所示。 3. 点击右上角的箭头&#xff0…

java内存马

java内存马 idea 2024.1.2专业版 jdk1.8.0_181 tomcat 8.5.82 默认有java基础&#xff0c;Javassist&#xff0c;Jsp&#xff0c;JavaEE都会一点 更新ing 文章目录 java内存马0. 一些基础1. filter型内存马2. Servlet型内存马3. listener型内存马4. Tomcat特有的Valve内存马…