如何优化Elasticsearch大文档查询?

news2025/1/17 6:27:56

记录一次业务复杂场景下DSL优化的过程

背景

B端商城业务有一个场景就是客户可见的产品列表是需要N多闸口及各种其它逻辑组合过滤的,各种闸口数据及产品数据都是存储在ES的(有的是独立索引,有的是作为产品属性存储在产品文档上)。

在实际使用的过程中,发现接口的毛刺比较严重,而这部分毛刺请求的耗时基本都是花费在从ES中查询产品索引的时候。

开启了一下ES慢DSL的日志

PUT /jiankunking_product_prod/_settings
{
  "index.search.slowlog.threshold.query.warn": "10s",
  "index.search.slowlog.threshold.query.info": "5s",
  "index.search.slowlog.threshold.fetch.warn": "2s",
  "index.indexing.slowlog.source": true
}

经过分析慢DSL日志发现耗时长的部分都是在fetch阶段。

这里有个地方需要注意

[root@jiankunking-search-01: /data/es/logs]# ls -lrth |grep -v .gz
total 2.2G
-rw-r--r-- 1 es es    0 Sep 30  2019 jiankunking_audit.json
-rw-r--r-- 1 es es    0 Sep 30  2019 jiankunking_index_indexing_slowlog.log
-rw-r--r-- 1 es es    0 Sep 30  2019 jiankunking_index_indexing_slowlog.json
-rw-r--r-- 1 es es  53M Dec 31  2023 jiankunking_deprecation.log
-rw-r--r-- 1 es es 108M Dec 31  2023 jiankunking_deprecation.json
-rw-r--r-- 1 es es  55K Jul 30 10:43 jiankunking_server.json
-rw-r--r-- 1 es es  52K Jul 30 10:43 jiankunking.log
-rw-r--r-- 1 es es  63M Jul 30 11:32 jiankunking_index_search_slowlog.log //这里是完整的DSL
-rw-r--r-- 1 es es 8.9M Jul 30 11:32 jiankunking_index_search_slowlog.json //这里的DSL会被截断

分析

已知问题点

  • 产品文档身上有4个属性会很大
    • 属性A(nested属性):可以到几万个
    • 属性B(nested属性):可以到几百个
    • 属性C(string数组):可以到几万个
    • 属性D(大Object):可以到几万个
  • ES fetch阶段慢,其实就是从相关分片请求文档内容慢(这时候id其实已经知道了)

大体就是下图这么个流程

在这里插入图片描述

下面简化一下请求的DSL,看下移除所有复杂的查询逻辑后,直接按照_id来terms查询效果如何?

DSL

GET /jiankunking_product_prod/_search
{
	"size": 10000,
	"_source": {
		"includes": [
			"code",
			"group",
			"groupBrand"
		],
		"excludes": []
	},
	"query": {
		"terms": {
			"_id": [
				"具体文档_id"
			]
		}
	}
}

不同文档大小查询时延

当前分析的DSL原本命中的文档数就是8306
下表中的文档数是直接在terms中查询的id数

文档数文档大小(Bytes)文档大小(KB)响应时延(ms)备注
8306无限制5908
5908<50,0000<4882327剔除大的
6929<20,0000<1951507剔除大的
5731<10,0000<97599剔除大的
4925<5,0000<49356剔除大的
4236❤️,0000<29214剔除大的(注意这里,当文档大小比较小的时候,4000+的文档查询其实是比较快的)
--------------------
4070>3,0000>296261剔除小的
3381>5,0000>496050剔除小的
2572>10,0000>975388剔除小的
1377>20,0000>1954973剔除小的
669>50,0000>4883984剔除小的
381>100,0000>9763169剔除小的
217>200,0000>19522391剔除小的
88>300,0000>29281244剔除小的

分析

  • 文档数与文档大小查询分析
    • 剔除大文档之后,查询数据效率提升明显
    • 剔除小文档之后,查询数据效率提升缓慢

到这里我们可以发现当文档size比较小的时候几千个文档的查询RT是很短的,但当随着请求命中的大文档越来越多,RT极速增加。

回看下我们的产品索引数据,可以发现大字段其实都是用来过滤的,并不是返回给页面需要的;那我们是不是可以:将索引拆分为两个或者ES只用来作为二级索引返回ids,然后去MySQL中查询具体的产品信息?

在这里插入图片描述

那我们将慢DSL中中查询的字段修改为只返回_id

POST /jiankunking_product_prod/_search
{
	"size": 10000,
	"_source": false,
	"query": {
		"terms": {
			"_id": [""],
			"boost": 1
		}
	}
}

这时候查询耗时只需要203ms,这种情况下还能不能再优化了呢?答案是可以的

索引中文档_id就是产品的code

POST /jiankunking_product_prod/_search
{
	"size": 10000,
	"_source": false,
	"stored_fields": "_none_",
	"docvalue_fields": [
		"code"
	],
	"query": {
		"terms": {
			"code": [
				""
			],
			"boost": 1
		}
	}
}

这时候查询只需要76ms

结论

到这里这次优化基本结束了,最终的方案就是

  • 通过从jiankunking_product_prod索引中通过列存获取ids
  • 到MySQL或者新的产品主数据索引中查询具体的产品数据

思考

为啥不直接从jiankunking_product_prod索引中通过列存获取前端需要的数据呢?

因为真实业务场景中需要返回的产品属性虽然每个不大,但总数有20多个,列存在返回字段数多且命中文档大小都不大的场景下,相比原逻辑直接从_source中取会略有下降。

更多原理性解释,可以看下这里:https://jiankunking.com/elasticsearch-source-doc-values-and-store-performance.html

ES适合的场景都有哪些?

目前我这边遇到的场景主要有:

  • 检索加速
    • 数据查询的主存储
      • 当文档大小不是太大的时候,索引检索完直接返回需要的数据
    • 二级索引
      • 针对的就是本文这种场景
  • 日志
    • 应用/容器日志
      • 这里追求的更多是高吞吐的写入
    • 业务日志

具体索引中数据大小是什么情况呢?

分位数大小 (KB)
0.051.16
0.101.39
0.151.61
0.201.69
0.251.77
0.302.14
0.352.97
0.403.50
0.453.90
0.504.24
0.554.92
0.605.73
0.657.15
0.708.82
0.7513.13
0.8032.32
0.8557.52
0.90114.39
0.95262.47
0.99989.75

在这里插入图片描述

拓展阅读

  • https://jiankunking.com/elasticsearch-source-doc-values-and-store-performance.html
  • https://jiankunking.com/elasticsearch-scroll-and-search-after.html
  • https://luis-sena.medium.com/stop-using-the-id-field-in-elasticsearch-6fb650d1fbae
  • https://jiankunking.com/elasticsearch-avoid-the-fetch-phase-when-retrieving-only-id.html
  • https://jiankunking.com/elasticsearch-query-secret.html
  • https://www.elastic.co/guide/en/elasticsearch/reference/current/general-recommendations.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在VS2022中用C++连接MySQL数据库读取数据库乱码问题

1.正确安装mysql 安装之后的配置文件 2.在VS2022中进行相关配置 &#xff08;1&#xff09;右键项目&#xff0c;打开属性 注意是右键项目&#xff0c;不是.cpp文件 &#xff08;2&#xff09;配置属性-> VC目录 -> 包含目录 ->添加头文件路径&#xff08;如图&am…

如何在linux系统上完成定时开机和更新github端口的任务

任务背景 1.即使打开代理&#xff0c;有的时候github去clone比较大的文件时也会出问题。这时需要每小时更新一次github的host端口&#xff1b; 2.马上要放假&#xff0c;想远程登录在学校的台式电脑&#xff0c;但学校内网又不太好穿透。退而求其次&#xff0c;选择定时启动电…

基于Java的语音陪聊软件——支持聊天私聊-礼物系统-直播系统-缘分匹配-游戏陪玩

丰富的经验、成熟的技术&#xff0c;打造适合当下市场发展的语音交友软件源码。Java 语言凭借其独特的优势&#xff0c;为这款语音陪聊软件的稳健运行和持续发展奠定了坚实基础。它不仅融合了聊天私聊、礼物系统和直播系统等实用且有趣的功能&#xff0c;还创新性地引入了缘分匹…

RV1126+FFMPEG推流项目(7)AI音频模块编码流程

一、AI 模块和外设麦克风的关系 AI 模块是 RV1126 芯片的一个重要组成部分。它的主要功能是将外部接入的麦克风采集到的模拟信号通过内置的驱动程序转换为数字信号。这意味着麦克风作为外设&#xff0c;提供音频输入信号&#xff0c;AI 模块通过其硬件和软件的结合&#xff0c…

计算机网络 (37)TCP的流量控制

前言 计算机网络中的TCP&#xff08;传输控制协议&#xff09;流量控制是一种重要机制&#xff0c;用于确保数据在发送方和接收方之间的传输既高效又稳定。 一、目的 TCP流量控制的主要目的是防止发送方发送数据过快&#xff0c;导致接收方无法及时处理&#xff0c;从而引起数据…

Python 实现 NLP 的完整流程

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

AIGC时代:如何快速搞定Spring Boot+Vue全栈开发

文章目录 一、Spring Boot基础二、Vue.js基础三、Spring Boot与Vue.js集成四、性能优化与最佳实践《快速搞定Spring BootVue全栈开发》 内容简介作者简介目录前言/序言本书内容本书特点读者对象 随着人工智能生成内容&#xff08;AIGC&#xff09;技术的迅速发展&#xff0c;…

【ArcGIS初学】产生随机点计算混淆矩阵

混淆矩阵&#xff1a;用于比较分类结果和地表真实信息 总体精度(overall accuracy) :指对角线上所有样本的像元数(正确分类的像元数)除以所有像元数。 生产者精度(producers accuracy) &#xff1a;某类中正确分类的像元数除以参考数据中该类的像元数(列方向)&#xff0c;又称…

《探秘火焰目标检测开源模型:智能防火的科技利刃》

一、引言 火灾&#xff0c;如同隐藏在暗处的恶魔&#xff0c;时刻威胁着人们的生命财产安全与社会的稳定发展。无论是澳大利亚那场肆虐数月、烧毁约1860万公顷土地、造成近30亿只动物死亡或流离失所的森林大火&#xff0c;还是美国加州频繁爆发、迫使大量居民撤离家园、带来巨额…

计算机网络 (46)简单网络管理协议SNMP

前言 简单网络管理协议&#xff08;SNMP&#xff0c;Simple Network Management Protocol&#xff09;是一种用于在计算机网络中管理网络节点的标准协议。 一、概述 SNMP是基于TCP/IP五层协议中的应用层协议&#xff0c;它使网络管理员能够管理网络效能&#xff0c;发现并解决网…

Java并发03 - 无锁三大将

无锁三大将&#xff1a;CAS & Unsafe & Atomic 文章目录 无锁三大将&#xff1a;CAS & Unsafe & Atomic一&#xff1a;CAS机制二&#xff1a;Unsafe魔法指针类2.1&#xff1a;内存管理2.2&#xff1a;对象创建实例2.3&#xff1a;类&#xff0c;实例对象以及变…

JVM远程调试原理剖析

一、如何开启JVM远程调试 当一个 Java 应用启动时&#xff0c;JVM 会根据启动参数配置其运行环境。使用 -agentlib:jdwp 参数启动远程调试功能&#xff0c;JVM 会初始化调试代理。 agentlib:jdwptransportdt_socket,servery,suspendn,address*:5005 -jar your_application.jar…

01、flink的原理和安装部署

flink中主要有两个进程&#xff0c;分别是JobMManager和TaskManager&#xff0c;当然了根据flink的部署和运行环境不同&#xff0c;会有一些不同&#xff0c;但是主要的功能是类似的&#xff0c;下面我会讲下聊下&#xff0c;公司用的多的部署方式&#xff0c;基于yarn集群的部…

浅谈云计算19 | OpenStack管理模块 (上)

OpenStack管理模块&#xff08;上&#xff09; 一、操作界面管理架构二、认证管理2.1 定义与作用2.2 认证原理与流程2.2.1 认证机制原理2.2.2 用户认证流程 三、镜像管理3.1 定义与功能3.2 镜像服务架构3.3 工作原理与流程3.3.1 镜像存储原理3.3.2 镜像检索流程 四、计算管理4.…

WXML模版语法-事件绑定

知识点1&#xff1a;什么是事件 事件是渲染层到逻辑层的通讯方式。通过事件可以将用户在渲染层产生的行为&#xff0c;反馈到逻辑层进行业务的处理。 知识点2&#xff1a;小程序中常用的事件 类型绑定方式事件描述tapbindtap或bind:tap手指触摸后马上离开&#xff0c;类似于…

深入解析 `EmailConfig` 配置项

EmailConfig 是 Alertmanager 配置中的一个重要部分&#xff0c;用于配置通过电子邮件发送告警通知。它提供了多种设置选项&#xff0c;以便用户可以灵活配置邮件服务器、认证方式、邮件内容等。 以下是 EmailConfig 配置项的详细分析&#xff0c;帮助你更好地理解其功能&…

Wine 开发系列 —— 如何调试 Wine

本文主要以 Wine 官网的这篇文章 《 Debugging Wine 》 来讲解。大部分内容是对该文的翻译&#xff0c;修正了原文的一些书写错误&#xff0c;删除了原文跟最新的 Wine 不适应的内容。 介绍 常用调试方法 Wine 为调试问题提供了多种方法。大多数 Wine 开发人员更喜欢使用 Win…

【精选】基于EfficientViT优化YOLOv8的智能车辆识别系统设计 车辆颜色分类与车牌检测、深度学习目标检测系统开发

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

自动化仓储管理与库存控制

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。欢迎大家到本文底部评论区留言。 完整版文件和更多学习资料&#xff0c;请球友到知识星球【智能仓储物流技术研习社】自行下载 本文是一本关于仓储管理与库存控制的教材&#xff0c;全…

redux 结合 @reduxjs/toolkit 的使用

1&#xff0c;使用步骤 使用React Toolkit 创建 counterStore&#xff08;store目录下&#xff09; --> 为React注入store&#xff08;src下面的index&#xff09; --> React组件使用store中的数据&#xff08;组件&#xff09; 2&#xff0c;例如下面有一个简单加减的…