有时我们只需要重放生产查询——无论是因为我们想要对产品的新版本进行真实的负载测试,还是因为我们想在测试环境中重现只在生产中出现的错误(这不是很可爱吗?什么时候发生?在测试中一切都很好,但是当你部署时,你的 日志 中出现大量异常,来自 监控 系统的大量警报......)。
使用 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 实践培训研讨会。 点击此处 了解详情!]