Elasticsearch 使用误区之四——不合理的使用 track_total_hits

0、企业级实战问题

在使用 Elasticsearch 进行搜索时,我们常常关心匹配查询的文档总数而将 track_total_hits 设置为 true,如下截图所示,在数据量非常大的情况下这种检索导致的问题是:查询特别慢,聚合会更慢!

5af2cfb7cc92103eb5832b901bf5e5a2.png

那么问题来了:

  • track_total_hits 引入的背景是什么?哪个版本才有的?

  • track_total_hits 含义是什么?

  • track_total_hits 什么时候需要设置 true ?

  • track_total_hits 什么时候设置 false?

  • track_total_hits 什么时候设置值?

  • track_total_hits 如何使用?

基于这些问题,本文逐步展开探讨。

1、track_total_hits 引入背景

在搜索引擎领域中,性能与准确性一直是开发者需要平衡的两个关键点。随着 Lucene 8(2019年4月前后)的推出,我们看到了几项重要的优化,这些优化不仅提升了搜索速度,还改变了我们获取搜索结果的方式。

特别是关于 track_total_hits 参数的变化,它直接关系到查询结果的性能表现和命中数的准确性。

Elasticsearch 在 7.0 版本集成了 Lucene 8 并引入这个特性。

https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html

track_total_hits 参数控制着 Elasticsearch 在返回查询结果时,如何计算匹配文档的总数。

过去,Elasticsearch 总是精确地计算总命中数,这意味着它必须遍历所有匹配的文档。显然,处理大量文档时代价高昂。

2、 track_total_hits 的工作原理

  • 默认行为:track_total_hits 设置为 false。

在Lucene 8中,如果不设置 track_total_hits,Elasticsearch 将默认使用 WAND 优化(WAND 优化算法本质——通过跳过不可能产生高分的文档来加快查询速度)。

这意味着当查询结果的总命中数超过一定阈值时(默认:10,000),Elasticsearch不再返回精确的命中数,而是返回一个下限值。

  • 准确计数:track_total_hits 人为修改设置为 true。

如果用户确实需要精确的命中数,可以通过将track_total_hits设置为 true 来强制Elasticsearch计算所有匹配文档的总数。然而,这会禁用WAND优化,从而导致性能下降(前文截图说慢,很大可能就是这里的原因)。

  • 设置阈值:用户自己设置 track_total_hits 阈值大小。

用户自己设置track_total_hits 为整数值(例如1000)时,如果匹配的文档总数超过了这个阈值,Elasticsearch 会返回的下限值就是我们设置的阈值本身,即1000,并指示命中数大于或等于1000。

如果这里有不理解,没关系,继续往后看,一会我们完整演示一遍。

3、 track_total_hits 设置后,和老版本(6及之前)显示不同点

当 track_total_hits 设置为默认值或较小的数值时,响应中的hits.total字段将包含一个对象,该对象包括命中数的值和关系,例如:

"hits": {"total": {"value": 10000,"relation": "gte"},
  • 当 relation 为 gte 时,表示实际的命中数大于或等于这个值。

  • 当 relation 为eq时,表示命中数是精确的。

除此之外,没有别的情况了。

4、拿真实样例数据演示一把

基础索引数据 test_index_0618, 共 100万条文档。

940a4612ac9b5ff247760180d3d39dc3.png

a14efc7b367f64361e7974c897e33059.png

4.1 track_total_hits 默认情况

如前所述,如果不做设置,默认支持最大文档数为 10000。

9f1cc949666c8134c098fc08a86d9bd7.png

通过执行结果可以看出,召回了 10000条数据,relation 代表确切含义:真实数据大于等于 10000。

4.2 track_total_hits 设置为 true

如果我们把  track_total_hits 设置为 true,依然执行 4.1 相同的检索语句。

9162e965c9ad46ffb0cc556d9624bd3a.png

执行结果可以看出,显示了真实文档数 100万,relation 是 “eq” 代表相等。

这个示例,也间接告诉我们:企业级实战环节,如果我们有复杂的检索、聚合操作,且数据量级也巨大(千万、亿、十亿甚至更多),如果track_total_hits 设置为 true,真的有可能产生检索效率极低的“灾难性”后果(相同硬件资源的前提下,数据量越大,检索可能越慢的共识大家都很清楚)。

4.3 track_total_hits 设置为给定值

这里的给定值,本质上是我们要修改的默认的阈值大小。比如这里,我们设置为 1000。

ad44875b49c77d597b98428a96c9b7cb.png

如结果展示,我们设置多大,最后召回数据就是多少。这个在真实业务场景中有选择的使用即可。

4.4 track_total_hits 设置为false

在一些性能敏感的场景下,我们可能根本不需要知道总命中数。

在这种情况下,我们可以将track_total_hits设置为false,以提高查询速度。

a21b15ef82b21afb2c4344031dea3f7e.png

如果所示,在这种情况下,返回结果中没有 total.value,意味着Elasticsearch并未计算总命中数,从而节省了大量的计算资源。

5、 track_total_hits 的性能权衡

track_total_hits 参数的核心在于它允许我们在命中数的准确性和查询性能之间做出权衡。

具体而言,如第4部分演示所示,这里总结如下表所示。

参数设置含义应用场景

track_total_hits: true

精确计算所有匹配文档的总数

适用于需要确切命中数的场景,但会牺牲查询性能。

track_total_hits: 1000

精确计算匹配文档的总数,直到达到指定上限(如1000)

在大部分情况下只关心部分准确的命中数,如需要快速查询并展示前几个结果。

track_total_hits: false

完全忽略总命中数的计算

对命中数不敏感且更关注查询速度的场景,例如仅需快速返回文档内容而不关注总命中数。

再次提醒:设置 track_total_hits 为 true时,会禁用 Max WAND 优化,这可能显著影响查询性能。因此,除非确有必要,否则建议谨慎使用。

6、总结

理解并合理使用track_total_hits参数,能够帮助我们在Elasticsearch中实现更高效的查询,同时避免不必要的性能开销。

其实所有的参数都建议我们抠一下细节后,必要时做一下性能测试后再应用到实战环节。

参考

https://github.com/elastic/elasticsearch/issues/33028

https://www.elastic.co/cn/blog/whats-new-in-lucene-8

https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html

https://www.elastic.co/guide/en/elasticsearch/reference/8.15/search-your-data.html#track-total-hits

更多推荐

Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!

  Elasticsearch 使用误区之二——频繁更新文档

  Elasticsearch 使用误区之三——分片设置不合理

   《一本书讲透 Elasticsearch》读者群的创新之路

38fc6ed9fb1ab1b12381bd73e01a2506.png

更短时间更快习得更多干货!

和全球2000+ Elastic 爱好者一起精进!

elastic6.cn——ElasticStack进阶助手

35553264e1c457c4d7536110c703fbcb.gif

抢先一步学习进阶干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/405109.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习:逻辑回归实现下采样和过采样

1、概述 逻辑回归本身是一种分类算法,它并不涉及下采样或过采样操作。然而,在处理不平衡数据集时,这些技术经常被用来改善模型的性能。下采样和过采样是两种常用的处理不平衡数据集的方法。 2、下采样 1、概念 下采样是通过减少数量较多的类…

MaxKB(二):Ubuntu24.04搭建maxkb开发环境

接上文:windows10搭建maxkb开发环境(劝退指南) 上文在windows10环境搭建maxkb开发环境遇到各种坑,后面就转战ubuntu平台,果然比较顺利的完成开发环境搭建。当然遇到相关的问题还是可以参考上文《windows10搭建maxkb开发…

Stable Diffusion赋能“黑神话”——助力悟空走进AI奇幻世界

《黑神话:悟空》是由游戏科学公司制作的以中国神话为背景的动作角色扮演游戏,将于2024年8月20日发售。玩家将扮演一位“天命人”,为了探寻昔日传说的真相,踏上一条充满危险与惊奇的西游之路。 同时,我们还可以借助AI绘…

向量数据库Faiss的搭建与使用

​ ​ 您好,我是程序员小羊! 前言 向量数据库在处理大量高维数据时非常有用,尤其在机器学习、推荐系统、图像检索和自然语言处理等领域。Faiss是 Facebook AI Research (FAIR) 开发的一款高效的开源向量数据库,专注于大规模、高维…

SpringBoot整合Sharding-JDBC分库分表

SpringBoot整合Sharding-JDBC分库分表 本文介绍SpringBoot使用当当Sharding-JDBC进行分库分表。 1、有关Sharding-JDBC 有关Sharding-JDBC介绍这里就不在多说,之前Sharding-JDBC是当当网自研的关系型数据库的水平扩展框架,现 在已经捐献给Apache&…

macOS安装搭建python环境

安装Homebrew apt-get是一个常见于Debian和Ubuntu等基于Linux的操作系统中的包管理工具,用于安装、更新和移除软件包。然而,macOS使用的是Homebrew或者MacPorts等其他的包管理工具,并不使用apt-get。 如果你想在macOS上使用类似apt-get的功…

【大模型理论篇】大模型时代下Bert去哪啦?

这个标题是最近看到的一篇文章《What happened to BERT & T5? On Transformer Encoders, PrefixLM and Denoising Objectives》有感而发,也感觉很有意思。在几年前,在项目中还经常会用到Bert。本文主要回顾一下Bert的原理、Bert的继续训练和使用&am…

JavaScript高级程序设计 -- -- 观后记录

一、什么是 JavaScript 1、JavaScript 实现 完整的 JavaScript 实现包含以下几个部分: -- --  核心(ECMAScript)  文档对象模型(DOM)  浏览器对象模型(BOM) 2、DOM 文档对象模型&#…

UE5 datetime 创建日期时间节点 进行加法减法。个人理解

以下均为个人实验和个人理解&#xff0c;仅供参考。 目录 目标节点&#xff1a; 年月日 时分秒毫秒 目标节点&#xff1a; 年月日 年月日以1 为基底。若填的数字<0&#xff0c;该节点会失效。 试验&#xff1a; year基底为1&#xff0c;正常 year基底为0&#xff0c;异…

SpringBoot 整合 Excel 轻松实现数据自由导入导出

01、背景介绍 在实际的业务系统开发过程中&#xff0c;操作 Excel 实现数据的导入导出基本上是个非常常见的需求。 之前&#xff0c;我们有介绍一款非常好用的工具&#xff1a;EasyPoi&#xff0c;有读者提出在数据量大的情况下&#xff0c;EasyPoi 会占用内存大&#xff0c;…

k8s综合项目

一、准备环境 1.1 部署服务器 在centos7.9系统里搭建v1.23版本的k8s集群&#xff0c;准备四台服务器&#xff0c;两台作为master&#xff0c;主机名分别为 k8s-master和k8s-master-2&#xff0c;主机名为k8s-master&#xff0c;两台作为 node&#xff0c;主机名分别为k8s-nod…

11-sentinel利用nacos作持久化

本文介绍sentinel配置数据的持久化方法。由于sentinel官方并没有提供持久化功能&#xff0c;大家在测试过程中也能发现sentinel服务重启后&#xff0c;原来配置的数据就丢了&#xff0c;本文就是来处理这一问题的。 做好心理准备&#xff0c;我们要修改sentinel的源代码&#…

C++ | Leetcode C++题解之第350题两个数组的交集II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {sort(nums1.begin(), nums1.end());sort(nums2.begin(), nums2.end());int length1 nums1.size(), length2 nums2…

【C++ 第十五章】map 和 set 的封装(封装红黑树)

1. map 和 set 的介绍 ⭐map 与 set 分别是STL中的两种序列式容器; 它们是一种树形数据结构的容器&#xff0c;且其的底层构造为一棵红黑树; 而在上一篇文章中提到,其实红黑树本身就是一棵二叉搜索树,是基于二叉搜索树的性质对其增加了平衡的属性来提高其综合性能 ⭐当然也…

【论文阅读】Retargeting and Respecializing GPU Workloads for Performance Portability

摘要 为了接近峰值性能&#xff0c;像gpu这样的加速设备需要大量的特定于架构的调优&#xff0c;以了解共享内存、并行性、tensor core等的可用性。不幸的是&#xff0c;对更高性能和更低成本的追求导致了架构设计的显著多样化&#xff0c;甚至是产自同一供应商的产品也是如此。…

Apache CloudStack Official Document 翻译节选(七)

关于 Apache CloudStack 的 最佳实践 &#xff08;一&#xff09; Best Practices 部署Apache CloudStack是极具挑战性的&#xff0c;在整个部署过程中需要你做出形形色色的技术性选择。Apache CloudStack的配置条目是相当灵活的&#xff0c;这是因为在组合和配置具体条目时有…

【深入浅出Docker】【三】Docker容器详解

文章目录 一. Docker容器简介二. Docker容器详解1. 容器vs虚拟机1.1. 虚拟机模型1.2. 容器模型1.3. 虚拟机的额外开销 2. 容器启动过程描述3. 容器进程4. 容器生命周期与文件保存5. 优雅地停止容器&#xff1a;两阶段方式停止并删除容器6. 利用重启策略进行容器的自我修复6.1. …

SpringBoot依赖之Spring Data Redis实现位图Bitmap

Spring Boot 项目中使用 Spring Data Redis 实现位图Bitmap 暂未发表&#xff0c;记录于20240820 概念 Spring Data Redis (AccessDriver) 依赖名称: Spring Data Redis (AccessDriver)功能描述: Advanced and thread-safe Java Redis client for synchronous, asynchronous,…

学习 node.js 六 Markdown 转为 html,zlib

目录 Markdown 转为 html 安装 ejs语法 标签含义 1. 纯文本标签 2. 输出经过 HTML 转义的内容 3. 输出非转义的内容(原始内容) marked browserSync zlib gzip deflate gzip 和 deflate 区别 http请求压缩 Markdown 转为 html 什么是markdown&#xff1f; Markdo…

分享思源笔记的几个骚操作

文章目录 思维导图复习法效果视频制作过程使用方法 大纲复习方法制作过程 人工智能简易使用效果制作过程 思维导图复习法 效果视频 bandicam20240817222246034.mp4 制作过程 首先下载【写味】主题或者是[自定义块样式]插件 他两个的区别是 思维导图以列表形式写出来 选择转…