使用 Logstash 和 JMeter 重放 Elasticsearch Slowlogs

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

有时我们只需要重放生产查询——无论是因为我们想要对产品的新版本进行真实的负载测试,还是因为我们想在测试环境中重现只在生产中出现的错误(这不是很可爱吗?什么时候发生?在测试中一切都很好,但是当你部署时,你的 日志 中出现大量异常,来自 监控 系统的大量警报......)。

使用 Elasticsearch,您可以启用 slowlogs 以使其记录花费(每个分片)时间超过特定阈值的查询。您可以根据需要更改设置。例如,以下请求将记录对 test-index 的所有查询:


 curl -XPUT localhost:9200/test-index/_settings -d '{
  "index.search.slowlog.threshold.query.warn" : "1ms"
}'

您可以通过 JMeter 等工具在测试环境中从慢日志运行这些查询。在本文中,我们将介绍如何使用 Logstash 解析慢速日志以仅将查询写入文件,以及如何配置 JMeter 以在 Elasticsearch 集群上运行来自该文件的查询。

使用 Logstash 解析慢日志

第一步是从慢日志中获取实际查询 JSON 并将其放入文件中,每行一个查询。这将使 JMeter 可以轻松地提取查询并重播它们。您可以在下面找到一个 Logstash 配置,该配置源自之前一篇关于 使用 Logstash 解析 Elasticsearch 日志的 帖子中描述的配置。我们感兴趣的字段是 source_body ,它包含每个查询。我们将通过 json_lines 编解码器 将它放入查询文件 ( /var/tmp/just_queries ) 每行一个。


 curl -XPUT localhost:9200/test-index/_settings -d '{
  "index.search.slowlog.threshold.query.warn" : "1ms"
}'

构建 JMeter 测试计划

接下来,我们需要 JMeter 测试计划才能运行它。为此,您需要下载并运行 JMeter,这将打开一个新的测试计划。右键单击左侧的“测试计划”图标,然后转到“添加”->“线程(用户)”-> “线程组” 。在那里,您可以指定有多少线程(好像它们是并发用户)将运行查询以及为每个线程运行多少查询。

在这个线程组下,我们将创建一个读取查询的配置元素,以及一个通过 HTTP 运行这些查询的采样器。

将查询读入变量

对于阅读查询,您可以使用 CSV 数据集配置 。您可以右键单击线程组,转到添加 -> 配置元素 -> CSV 数据集配置。您必须添加包含查询的文件名(本例中为 /var/tmp/just_queries )、获取查询的变量名(本例中为 BODY )并指定查询由换行符分隔( \n ).

在 HTTP 请求中使用变量

对于 BODY 变量中的查询,最后一步是创建一个将运行这些查询的 HTTP 请求 采样器。右键单击线程组,转到添加 -> 采样器 -> HTTP 请求。然后,您需要进行以下更改:
– 指定要在其上运行查询的主机和端口。如果你远程运行它们,它很可能是 localhost:9200
– 将 Method 更改为 POST 。这很重要,因为 GET 会忽略您的查询所在的帖子正文
– URL 路径。通常是 INDEX-NAME/_search
– 指定 ${BODY} 将是 Post Body

使用 JMeter 远程运行查询

如果您的集群位于远程数据中心(或云中),我会避免通过 WAN 运行查询,因为它会引入延迟并可能使测试无效。相反,您可以在远程机器上下载 JMeter,将测试计划复制过来并在那里运行:


 curl -XPUT localhost:9200/test-index/_settings -d '{
  "index.search.slowlog.threshold.query.warn" : "1ms"
}'

然后您可以将结果文件复制回您的机器并使用 JMeter 的 GUI 对其进行分析。

检查结果

为了检查结果,JMeter 提供了相当多的聚合。通常,我只需要汇总数字,为此我使用 摘要报告 (右键单击测试计划 -> 添加 -> 侦听器 -> 摘要报告)。在那里,我可以浏览 JTL 文件并将其打开以查看平均查询时间、吞吐量等:

检查单个查询结果

如果您发现结果有问题(例如查询时间太短),您可以使用 结果树 视图检查 Elasticsearch 对每个查询的回复。您可能希望为此使用 JMeter 的 UI,并从您自己的机器转发请求,您可以通过 SSH 转发远程服务器端口:


 curl -XPUT localhost:9200/test-index/_settings -d '{
  "index.search.slowlog.threshold.query.warn" : "1ms"
}'

然后您将从本地 JMeter 对 localhost:9200 运行查询。

要在运行测试时查看结果,您可以右键单击线程组并转到添加 -> 侦听器 -> 查看结果树。在那里,您可以选择任何查询并查看发送到 Elasticsearch 的请求和回复,看看它是否符合您的期望。

最后的话

此过程有一些限制——以下是我所知道的两大限制:
– 我们正在针对硬编码索引运行查询。理想情况下,我们将从慢日志中提取索引名称并将其用作 JMeter 中的变量
– slowlogs 是每个分片的,所以如果客户端查询命中五个分片并且所有分片都超过了 slowlog 阈值,那么日志中将有五个相同的查询,JMeter 将重播它们。您可能只从其中一个分片获得一个查询(例如,通过过滤 Logstash 中的分片编号),但通常在负载测试中,如果您在集群上增加一些负载就没问题。

我希望这篇文章对您有用,如果这类内容让您兴奋,我很高兴地说 Sematext 正在 全球范围内招聘 。您也可以关注我们 @sematext


[ 注意: 我们将于 2015 年 10 月 19 日至 20 日在纽约举办为期 2 天的 Elasticsearch / ELK Stack 实践培训研讨会。 点击此处 了解详情!]