如何解决 Elasticsearch 查询缓慢的问题以获得更好的用户体验

作者:Philipp Kahr

Elasticsearch Service 用户的重要注意事项:目前,本文中描述的 Kibana 设置更改仅限于 Cloud 控制台,如果没有我们支持团队的手动干预,则无法进行配置。 我们的工程团队正在努力消除对这些设置的限制,以便我们的所有用户都可以启用内部 APM。 本地部署不受此问题的影响。

对于任何使用 Elasticsearch 作为搜索引擎的人来说,识别查询并排除查询故障是一项需要掌握的关键技能。 无论是电子商务、可观察性还是面向工作场所的搜索解决方案,缓慢的 Elasticsearch 都会对用户体验产生负面影响。

要查明慢速 Elasticsearch 查询,你可以使用慢速日志,它捕获在特定阈值运行的查询。 正确设置慢日志阈值本身就是一个挑战。 例如,在满负载下花费 500 毫秒的查询可能是可接受的,但在低负载下相同的查询可能是不可接受的。 慢日志不区分并记录 500 毫秒以上的所有内容。 慢日志很好地完成了它的工作,你可以根据阈值捕获不同级别的粒度。 相反,跟踪可以查看所有查询,确定有多少查询在特定阈值内。

应用程序性能监控 (APM) 不再仅限于你的应用程序。 使用 Elasticsearch 中的检测,我们现在可以将 Elasticsearch 添加为成熟的服务,而不是对应用程序堆栈的依赖。 通过这种方式,我们可以获得比慢速日志更细致的性能视图。

对于以下示例,我们的数据语料库是 OpenWebText,它提供大约 40GB 的纯文本和大约 800 万个单独文档,这些文档在具有 32GB RAM 的 M1 Max Macbook 上本地运行。

让我们开始吧!

在 Elasticsearch 中激活跟踪是通过静态设置(在 elasticsearch.yml 中配置)和动态设置完成的,可以在运行时使用 PUT _cluster/settings 命令进行切换,其中动态设置之一是采样率。 某些设置(例如采样率)可以在运行时切换。 在 elasticsearch.yml 中我们要设置以下内容:

tracing.apm.enabled: true
tracing.apm.agent.server_url: "url of the APM server"

秘密令牌(或 API 密钥)必须位于 Elasticsearch 密钥库中。 使用以下命令 elasticsearch-keystore add Tracing.apm.secret_token 或 Tracing.apm.api_key 应该可以在 <your elasticsearch install directory>/bin/elasticsearch-keystore 中找到密钥库工具。 之后,你需要重新启动 Elasticsearch。 有关跟踪的更多信息可以在我们的跟踪文档中找到。

一旦 APM 处于活动状态,我们就可以查看 Kibana 中的 APM 视图,并看到 Elasticsearch 自动捕获各种 REST API 端点。 在这里,我们主要关注 POST /{index}/_search 调用,看看我们能从中获得什么。

通过直接检查 GET /{index}/_search 框上的简单查询,我们看到以下瀑布细分。 其中包含内部跨度(span),可以更深入地了解 Elasticsearch 在幕后所做的事情。 我们看到这次搜索的总持续时间(86 毫秒)。

查询附带的元数据包括有关 HTTP 标头、用户代理、Elasticsearch 节点位置(云提供商元数据、主机名、容器信息)、一些系统信息和 URL 详细信息的大量信息。 使用一些基本的交易信息,我们可以创建一个透镜图,绘制平均交易持续时间,并允许我们查看是否存在上升或下降趋势。

我们的搜索应用程序

很高兴不再需要使用慢日志! 我可以确定交易持续时间并确定在任何阈值下回答了多少搜索。 然而,有一个挫折 —— Elasticsearch 不会捕获发送的查询(查询的具体内容是什么),因此我们知道查询花费了很长时间,但我们不知道查询是什么。

让我们测试一个示例搜索应用程序。 在本例中,我们将使用一个简单的 Flask 应用程序,其中包含两个路由:search_single 和 search_phrase,它们将表示 Elasticsearch 中的 match 和 match_phrase 查询。 例如,我们可以使用以下查询:

{"query": {"match": {"content": "support"}}
}

{"query": {"match_phrase": {"content": "support protest"}}
}

以下 Flask 代码实现了 search_single 路由。 search_phrase 非常相似,只是它使用 match_phrase 而不是 match。

@app.route("/search_single", methods=["GET"])
def search_single():query = request.args.get("q", "")if not query.strip():return jsonify({"error": "No search query provided"}), 400try:result = es.search(index=ES_INDEX, query={"match": {"content": query}})hits = result["hits"]["hits"]response = []for hit in hits:response.append({"score": hit["_score"],"content": hit["_source"]["content"],})return jsonify(response)

准备就绪后,我现在可以调用 curl -XGET “http://localhost:5000/search_single?q='microphone'” 来搜索术语 “microphone”。

我们主要将 APM 添加到我们的搜索应用程序中进行观察,但我们的 APM 代理捕获传出请求并使用元数据信息丰富它们。 在我们的例子中,span.db.statement 包含 Elasticsearch 查询。 在下面这个例子中,有人搜索了 window.

将它们拼凑在一起

在我的 Flask 服务中,我将查询大小设置为 5,000,这意味着 Elasticsearch 应在单个 JSON 响应中为我提供最多 5,000 个匹配文档。 这是一个很大的数字,并且大部分时间都花在从磁盘检索这么多文档上。 将其更改为前 100 个文档后,我可以通过比较快速识别仪表板中发生的情况。

在 APM 视图中查看 transaction 并激活关键路径的实验室功能会创建一个覆盖层,向我们显示应用程序将时间花在哪里。

之后,我使用字段 transaction.duration.us、es_query_took、transaction.name 创建了一个仪表板。 一般 KQL 过滤器包含 service.name、processor.event: transaction、transaction.name: POST /{index}/_search。

附加提示:转到数据视图管理 > 选择包含 APM 数据流的数据视图 > 选择 transaction.duration.us 字段 > 并将格式更改为 duration。 现在它会自动以人类可读的输出而不是 microseconds 的形式呈现它。

利用 Lens 注释(annotation)功能,我们可以在中间 Lens 中看到,更改为 100 个文档使平均搜索 transaction 量下降了很多。 不仅如此,查看右上角的记录总数。 由于我们可以更快地搜索,因此我们有更高的吞吐量! 我真的很喜欢直方图,因此我在顶行的中间创建了一个直方图,其中 X 轴为交易持续时间,Y 轴为记录数。 此外,APM 还提供指标,因此我们可以随时确定发生了多少 CPU% 使用情况以及 JVM 堆、非堆使用情况、线程计数和更多有用信息。

 

结论

这篇博文向您展示了将 Elasticsearch 作为仪表化应用程序并更轻松地识别瓶颈是多么重要。 此外,你还可以使用事务持续时间作为异常检测的指标,为你的应用程序进行 A/B 测试,并且再也不用怀疑 Elasticsearch 是否感觉更快,因为你现在有数据可以回答这个问题。 此外,从用户代理收集到查询的所有元数据都可以帮助你排除故障。

可以从此处导入仪表板和数据视图。

警告
Elasticsearch 内部的 transaction duration 存在问题。 此问题已在即将发布的 8.9.1 版本中修复。 在此之前,transaction 使用错误的时钟,这会扰乱整体持续时间。

本文中描述的任何特性或功能的发布和时间安排均由 Elastic 自行决定。 当前不可用的任何特性或功能可能无法按时交付或根本无法交付。

原文:How to troubleshoot slow Elasticsearch queries for better user experience | Elastic Blog

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

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

相关文章

传统图像算法 - 运动目标检测之KNN运动背景分割算法

以下代码用OpenCV实现了视频中背景消除和提取的建模&#xff0c;涉及到KNN&#xff08;K近邻算法&#xff09;&#xff0c;整体效果比较好&#xff0c;可以用来进行运动状态分析。 原理如下&#xff1a; 背景建模&#xff1a;在背景分割的开始阶段&#xff0c;建立背景模型。 …

1999-2021年全国各地级市专利申请与获得情况、绿色专利申请与获得情况面板数据

1999-2021年全国各地级市专利申请与获得情况、绿色专利申请与获得情况面板数据 1、时间&#xff1a;2000-2021年 2、来源&#xff1a;国家知识产权局 3、范围&#xff1a;地级市&#xff08;具体每年地级市数量参看下文图片&#xff09; 4、指标&#xff1a;申请专利数&…

Jenkins 中 shell 脚本执行失败却不自行退出

Jenkins 中 执行 shell 脚本时&#xff0c;有时候 shell 执行失败了&#xff0c;或者判断结果是错误的&#xff0c;但是 Jenkins 执行完成后确提示成功 success 。 此时&#xff0c;可以通过条件判断来解决这个问题&#xff0c;让 Jenkins 强制退出并提示执行失败 failed 。 …

【MySQL系列】表约束的学习

「前言」文章内容大致是MySQL的表的约束。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、MySQL表的约束1.1 空属性1.2 默认值&#xff08;default&#xff09;1.3 列描述&#xff08;comment&#xff09;1.4 zerofill1.5 主键&#xff08;primary ke…

stm32_断点调试无法进入串口接收中断

先说结果&#xff0c;可能是stm32调试功能/keil软件/调试器&#xff08;试过STLINK和JLINK两种&#xff09;的问题&#xff0c;不是代码&#xff1b; 1、入坑 配置完串口后&#xff0c;可以发送数据到串口助手&#xff0c;但不能接收数据并做处理&#xff0c;所以第一步&…

【阻止IE强制跳转到Edge浏览器】

由于微软开始限制用户使用Internet Explorer浏览网站&#xff0c;IE浏览器打开一些网页时会自动跳转到新版Edge浏览器&#xff0c;那应该怎么禁止跳转呢&#xff1f; 1、点击电脑左下角的“搜索框”或者按一下windows键。 2、输入“internet”&#xff0c;点击【Internet选项…

LabVIEW开发分段反射器测试台

LabVIEW开发分段反射器测试台 随着对太空的观察需求越来越远&#xff0c;而不是当前技术&#xff08;如哈勃望远镜&#xff09;所能达到的&#xff0c;有必要增加太空望远镜主镜的尺寸。但是&#xff0c;增加主镜像的大小时存在几个问题。随着反射镜尺寸的增加&#xff0c;制造…

vue3官网文档学习、复习笔记(快速上手)

目录 2.Attribute 绑定&#xff08;v-bind&#xff09; 3.事件监听&#xff08;v-on&#xff09; 4.表单绑定&#xff08;v-model&#xff09; 5.条件渲染&#xff08;v-if&#xff09; 6.列表渲染&#xff08;v-for&#xff09; all.value all.value.filter&#xff08;…

【MySQL】表中的一条数据在磁盘上是如何存放的?

文章目录 1 InnoDB行格式2 COMPACT行格式2.1 记录的额外信息2.2 记录的真实数据 3 Dynamic & Compressed4 VarChar(n)中n的最大取值&#xff1f; 1 InnoDB行格式 不同的存储引擎一般是为实现不同的特性来开发的&#xff0c;真实数据在不同存储引擎中的存放格式一般是不同的…

机器学习基础

什么是机器学习&#xff1f;----本质就是寻找一个函数。 可以训练什么样的函数呢&#xff1f; 可以训练一个回归的函数&#xff0c;也可以训练一个分类的函数。 这个例子的需要分类的类别是19*19的选项。 在机器学习领域里面不止回归和分类。 举例&#xff1a;预测函数 利用已…

Nginx(3)

目录 1.Nginx虚拟主机1.1基于IP虚拟主机1.2基于端口虚拟主机1.3基于域名实现的虚拟主机 2.日志详解 1.Nginx虚拟主机 虚拟主机&#xff0c;Nginx配置中的多个server{}区域对应不同的业务(站点) 虚拟主机方式基于域名的虚拟主机不同的域名访问不同的站点基于IP的虚拟主机不同的…

第一百二十五天学习记录:C++提高:STL-deque容器(下)(黑马教学视频)

deque插入和删除 功能描述&#xff1a; 向deque容器中插入和删除数据 函数原型&#xff1a; 两端插入操作&#xff1a; push_back(elem); //在容器尾部添加一个数据 push_front(elem); //在容器头部插入一个数据 pop_back(); //删除容器最后一个数据 pop_front(); //删除容器…

低成本NFC端口静电保护方案图及ESD二极管选型指南

Near Field Communication&#xff0c;简称&#xff1a;NFC&#xff0c;中文名称&#xff1a;近场通信&#xff0c;是一种短距离高频的无线电技术&#xff0c;能够实现近距离无线通讯和数据交换&#xff0c;是由非接触式射频识别&#xff08;RFID&#xff09;及互连互通技术整合…

微服务学习笔记-基本概念

微服务是一种经过良好架构设计的分布式架构方案。根据业务功能对系统做拆分&#xff0c;每个业务功能模块作为独立项目开发&#xff0c;称为一个服务。 微服务的架构特征&#xff1a; 单一职责&#xff1a;微服务拆分粒度更小&#xff0c;每一个服务都对应唯一的业务能力&…

数据标注对新零售的意义及人工智能在新零售领域的应用?

数据标签对于新零售至关重要&#xff0c;因为它构成了训练和部署人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;模型的基础。在新零售的背景下&#xff0c;数据标签涉及对数据进行分类、标记或注释以使其能够被机器理解的过程。然后&#xff0c;这些…

Qt应用开发(基础篇)——框架类 QFrame

一、前言 QFrame继承于QWidget&#xff0c;被QLCDNumber、QToolBox、QLabel、QListView等部件继承&#xff0c;是一个拥有矩形框架的基类。 QFrame可以直接创建成一个没有内容的的矩形框架&#xff0c;框架的样式由边框厚度(lineWidth)、框架形状(QFrame::Shape)和阴影样式(QFr…

浏览器多管闲事之跨域

年少时的梦想就是买一台小霸王游戏机 当时的宣传语就是小霸王其乐无穷~。 大些了&#xff0c;攒够了零花钱&#xff0c;在家长的带领下终于买到了 那一刻我感觉就是最幸福的人 风都是甜的&#xff01; 哪成想... 刚到家就被家长扣下了 “”禁止未成年人玩游戏机 (问过卖家了&a…

Transformer理论学习

Transformer出自于论文《attention is all you need》。 一些主流的序列模型主要依赖于复杂的循环结构或者CNN&#xff0c;这里面包含了编解码器等。而Transformer主要的结构是基于注意力机制&#xff0c;而且是用多头注意力机制去替换网络中的循环或者CNN(换言之就是transfor…

CD4029计数器实测仿真及BCD转七段码

前面的博文中&#xff0c;我们介绍过CD40110(这是一个常见的直接接7段数码管的计数器&#xff0c;我们这里介绍一款新的计数器CD4029&#xff0c;这也是很常见的计数器&#xff0c;不同的是后者可以输出BCD编码。 文章目录 一、总体效果二、CD4029的管脚和功能介绍1、芯片功能简…

使用 PowerShell 将 Excel 中的每个工作表单独另存为独立的文件

导语&#xff1a;在日常工作中&#xff0c;我们经常需要处理 Excel 文件。本文介绍了如何使用 PowerShell 脚本将一个 Excel 文件中的每个工作表单独另存为独立的 Excel 文件&#xff0c;以提高工作效率。 1. 准备工作 在开始之前&#xff0c;请确保已经安装了 Microsoft Exc…