mcpField
V
vm-trace-analyzer

vm-trace-analyzer

github.com/victoriametrics云与 DevOps59253 次安装2 周前更新
代码仓库

关于 vm-trace-analyzer

vm-trace-analyzer 是一项从 VictoriaMetrics 查询跟踪 JSON 生成性能报告的技能。它通过脚本汇总跟踪数据并检查较新版本的变更日志,再定位主要耗时阶段并给出基于证据的建议。

主要功能

  1. 01解析跟踪数据并生成摘要
  2. 02检查跟踪树和匹配节点
  3. 03按查询阶段拆分耗时
  4. 04报告各 vmstorage 节点详情
  5. 05检查较新版本的 VictoriaMetrics 变更日志
  6. 06依据瓶颈选择建议

适用场景

  1. 01诊断缓慢的 PromQL 查询
  2. 02比较各 vmstorage 节点的查询阶段
  3. 03查看较新版本中的性能修复

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/victoriametrics/skills --skill vm-trace-analyzer

安装后在 Claude Code 中输入/vm-trace-analyzer确认已加载。

附带文件scripts/check_changelog.pyscripts/parse_trace.py

详细介绍

VictoriaMetrics 查询跟踪分析器

你正在分析 VictoriaMetrics 查询跟踪——一种记录 PromQL 查询执行每个步骤的 JSON 树。你的目标是读取这棵树,了解执行过程,并生成清晰的性能报告及可行的改进建议。

背景

在 Cluster 模式下,查询处理涉及两个组件:

  • vmselect — 查询前端,负责接收 PromQL 或 MetricsQL 查询、从 vmstorage 节点获取数据并执行计算
  • vmstorage — 存储时间序列数据,并通过 RPC 将数据提供给 vmselect

Single-node 模式在一个进程中运行所有功能。跟踪结构类似,但不包含 RPC 封装。

你可以根据跟踪中的根消息判断所处的模式:

  • Cluster 跟踪包含 vmselect-<version>: /select/...,
  • Single-node 跟踪包含 /victoria-metrics-<version>: /api/v1/...。

什么是查询跟踪?

在 VictoriaMetrics HTTP 查询中添加 trace=1 后,它会返回一棵描述每项内部操作的 JSON 树。 每个节点如下所示:

{
  "duration_msec": 123.456,
  "message": "description of what happened",
  "children": [ ... ]
}

这棵树以 vmselect 为根节点,记录了完整的查询执行流程:解析、序列搜索、从存储中获取数据、rollup 计算、聚合和响应生成。

如何分析跟踪

步骤 0:运行解析脚本

手动阅读跟踪文件之前,先运行分析脚本提取结构化数据:

python3 <skill_base_dir>/scripts/parse_trace.py <trace_file>

该脚本会输出:根节点信息、跟踪树(深度为 3)、包含耗时的关键节点、各 vmstorage 的 RPC 明细,以及计算得出的总量(字节数、样本数、序列数)。将此输出作为报告的主要数据来源。

用于深入调查的其他子命令:

  • python3 <script> <trace> tree --depth N — 打印深度为 N 的跟踪树
  • python3 <script> <trace> nodes --pattern "fetch unique" — 查找所有包含指定子字符串的节点

只有在摘要输出存在歧义或信息缺失时,才进一步深入调查。

运行摘要后,还要检查较新 VictoriaMetrics 版本中的相关性能改进:

python3 <skill_base_dir>/scripts/check_changelog.py <version> <mode>

其中,<version> 是解析脚本输出的语义化版本号(例如 v1.130.0),<mode> 为 cluster 或 single-node。此命令会从 GitHub 获取变更日志,并显示跟踪采集版本之后版本中与性能相关的修复和功能。如果获取失败,请跳过此部分。

步骤 1:从根节点开始

读取用户提供的跟踪 JSON 文件(或使用步骤 0 的脚本输出)。 根节点展示了整体情况。提取以下信息:

  • Endpoint:/api/v1/query(即时查询)或 /api/v1/query_range(范围查询)
  • Query:query= 后面的 PromQL 表达式
  • 时间参数:范围查询的 start=、end=、step=
  • 结果数量:末尾的 series=
  • 总耗时:根节点的 duration_msec
  • 版本:跟踪开头显示的版本。
步骤 2:识别各阶段

遍历顶层子节点,并将每个子节点归类到以下某个阶段。 并非每条跟踪记录都包含所有阶段,只需报告实际出现的阶段。

对于较大的跟踪记录,先关注顶层子节点。 仅当子树与瓶颈相关或耗时异常时,才深入查看。

查询跟踪记录通常包含以下阶段,顺序大致如下。 并非每条跟踪记录都会出现所有阶段。请根据此处描述的消息模式识别各阶段。

表达式求值 — 匹配以下内容的节点:eval: query=..., timeRange=..., step=..., mayCache=...: series=N, points=N, pointsPerSeries=N 这些节点记录 PromQL/MetricsQL 表达式树的递归求值。 这些节点记录 PromQL/MetricsQL 表达式树的递归求值。 每个 eval 节点都可能包含子表达式对应的子节点。关键数字:

  • series — 此子表达式生成的时间序列数
  • points — 所有时间序列的数据点总数
  • pointsPerSeries — 每条时间序列的数据点数

函数与聚合 — 匹配以下内容的节点:

  • transform <func>(): series=N — PromQL 函数(histogram_quantile、clamp 等)
  • aggregate <func>(): series=N — 聚合运算符(sum、avg、max 等)
  • binary op "<op>": series=N — 二元运算

序列搜索(索引查找) — 根据标签匹配器查找对应的内部序列 ID:

  • 在 Cluster 跟踪记录中,包含在 rpc at vmstorage <addr> → rpc call search_v7() 之下;在 Single-node 中,会直接出现,不带 RPC 封装
  • 关键消息:
    • init series search,
    • search TSIDs,
    • search N indexDBs in parallel — 并行搜索索引数据库,
    • search indexDB — 单个索引分区,
    • found N metric ids for filter=... — metric ID,即 vmstorage 内唯一的时间序列标识符,
    • found N TSIDs for N metricIDs — 与 metric ID 相同,
    • sort N TSIDs
  • 此阶段与缓存相关的消息:
    • search for metricIDs in tag filters cache 后跟 cache miss 或缓存命中(没有 cache miss 子节点)
    • put N metricIDs in cache / stored N metricIDs into cache

数据获取 — 获取原始数据:

  • Cluster:fetch matching series: ... 包含对各 vmstorage 节点的 RPC 调用:
    • rpc at vmstorage <addr> — 每个节点的 RPC,
    • sent N blocks to vmselect — 传回的数据块数量,
    • fetch unique series=N, blocks=N, samples=N, bytes=N — 所有 vmstorage 节点的汇总数据,
  • Single-node:search for parts with data for N series 后跟数据扫描消息。 fetch unique series 中的 bytes 值表示传输的数据总量,是 I/O 负载的良好指标。

汇总计算 — 计算 rate()、increase()、avg_over_time() 等:

  • rollup <func>(): timeRange=..., step=N, window=N
  • rollup <func>() with incremental aggregation <agg>() over N series — 这是一种优化
  • the rollup evaluation needs an estimated N bytes of RAM for N series and N points per series — 内存估算
  • parallel process of fetched data: series=N, samples=N — 对原始样本执行的实际计算
  • series after aggregation with <func>(): N; samplesScanned=N — 聚合后的结果 对于扫描大量原始数据的查询,此阶段通常占据大部分执行时间。

响应生成 — 通常非常简单:

  • sort series by metric name and labels
  • generate /api/v1/query_range response for series=N, points=N 通常速度非常快。如果响应很大(数百条序列,每条序列有数千个数据点),且客户端读取响应的速度较慢,则此阶段可能成为瓶颈。
步骤 3:细分耗时

记录每个阶段的 duration_msec。 在 Cluster 跟踪记录中,相同阶段会在每个 vmstorage 节点上重复出现 — 汇总时应计算总量,同时也要记录各节点的数据,以发现不均衡情况。

步骤 4:找出瓶颈

找出耗时最长的阶段,并具体说明原因。 例如,“rollup 扫描了 2.12 亿条原始样本”是有用的信息;“查询很慢”则不是。

步骤 5:编写建议

建议只能基于追踪实际显示的信息。 如果查询快速且运行良好,就如实说明——不要凭空捏造问题。

按照以下算法选择建议:

  • 步骤 5a: 根据耗时明细,找出占总延迟比重最大的单个阶段(>60%)。将其对应到下方“建议模式”部分中的匹配模式。
  • 步骤 5b: 仅使用该模式中的建议,并按照列出的优先级排序。不要从其他模式中提取建议。
  • 步骤 5c: 如果没有任何单个阶段超过 60%,选择占比最高的模式,并指出次要因素,但仍不要混用不同模式中的建议。

报告格式

## Query Overview

- **Query:** `<the PromQL/MetricsQL expression>`
- **Type:** instant / range query
- **Time range:** <start> to <end> (<duration>)
- **Step:** <step>
- **Result:** <N> series, <N> points
- **Version:** vmselect or VM single-node version

## Performance Summary

- **Total duration:** <N>ms
- **Duration score:** <Fast / Acceptable / Slow / Very Slow>
- **Matched series:** <N> (across all storage nodes)
- **Raw samples scanned:** <N>
- **Bytes transferred:** <N>

"Duration score" thresholds:
- Fast: < 500ms
- Acceptable: 500ms–5s
- Slow: 5s–10s
- Very Slow: > 10s

## Execution Time Breakdown

| Phase | Duration | % of Total | Notes |
|-------|----------|------------|-------|
| Series search (index) | Xms | X% | |
| Data fetch | Xms | X% | |
| Rollup computation | Xms | X% | |
| Aggregation / functions | Xms | X% | |
| Response generation | Xms | X% | |

(Adapt the phases to what actually appears in the trace. 
For cluster traces, break down data fetch per storage node.)

## Storage Node Breakdown (cluster only)

| Node | Series | Bytes sent | Duration |
|------|--------|-------------|----------|
| vmstorage-1 | N | N | Xms |
| vmstorage-2 | N | N | Xms |

## Bottleneck Analysis

Name the single biggest contributor to total query time. Explain why it's slow with specific numbers from the trace.

## Recommendations

Provide actionable suggestions to reduce query latency (see guidance below).

## Upgrade Recommendations (if applicable)

If the changelog check found performance-relevant improvements in newer versions,
list them here with version, release date, and description.
Only include this section if there are concrete relevant entries. Omit entirely otherwise.

报告生成规则

  • 不要推测追踪中没有证据支持的问题。如果追踪显示运行良好且查询快速,就如实说明。
  • 报告中不要展示块的信息——这对用户没用,还可能造成困惑。重点关注字节数。
  • 除非 vmstorage 节点之间的 Duration 相差超过 1-2s,否则不要提及这种差异。
  • 耗时使用“Xm”/“Xs”/“Xms”格式(例如“123ms”);仅当耗时超过 60s 时使用分钟,超过 1000ms 时使用秒,更短的耗时使用毫秒。
  • 数据量使用易读格式(例如,用“268 MB”代替“268000000 bytes”)。根据大小选择合适的单位(KB、MB、GB)。
  • 直接使用追踪中的 duration_msec 值——不要通过相减估算耗时。
  • 在集群追踪中,相同的阶段(索引搜索、数据扫描)会出现在每个 vmstorage 节点中。汇总时合并这些阶段,同时也展示各节点的明细,以便用户发现负载不均。
  • 如果追踪太大,无法一次读完,请先阅读顶层结构,根据 duration_msec 找出最慢的分支,再深入查看这些分支。
  • 某些追踪可能包含 subquery 或 @ modifier 求值——应将其视为嵌套的 eval 阶段。
  • eval 消息中的 mayCache=false 仅供参考,并不代表存在问题

建议模式

重要:模式选择规则

  1. 首先,根据耗时明细确定以下哪一种模式与瓶颈相符。
  2. 仅使用该模式中的建议,并按列出的优先级排序。
  3. 不要混用不同模式的建议。如果主要阶段占总延迟的 60% 以上,则所有建议都必须仅来自该模式。
  4. 如果某项建议出现在多个模式中,并不意味着它与模式无关——仅当它列在你所选的模式中时才使用。

根据追踪实际显示的情况,按优先级提出建议。 以下是常见模式及相应建议:

序列基数高(匹配的序列很多)

  1. 建议添加更具体的标签匹配器,以减少序列数量
  2. 如果这是仪表板查询,建议使用记录规则进行预聚合
  3. 如果可行,建议使用流式聚合,在存储前对序列进行预聚合
  4. 如果匹配的指标具有较高的变更率,建议缩短时间范围

原始样本扫描量大(samplesScanned 高)

  1. 如果 samplesScanned 的数量远超获取的样本数量,则说明查询使用的 [window] 过短或子查询过于激进。
  2. 对于 rate()/irate()/increase(),如果语义上可接受,建议使用较短的 [window]
  3. 建议增大查询步长,以减少每条序列的数据点数量
  4. 建议缩短时间范围

索引查找缓慢(序列搜索占主导)

  1. 标签筛选器缓存未命中在首次查询时很正常;请说明重复查询应该会更快
  2. 每日分区中的指标 ID 数量很多,说明可能存在高变更率或高基数问题
  3. 如果可行,建议使用选择性更高的筛选器
  4. 如果可行,建议增加 vmstorage 节点的内存

数据获取缓慢/传输字节数高(集群)

  1. 发送字节数较大,说明 vmstorage 正在进行大量 I/O
  2. 如果资源达到饱和,建议在 VictoriaMetrics 官方 Grafana 仪表板中检查资源使用情况。
  3. 建议检查 vmstorage 的磁盘 I/O 和网络带宽
  4. 多个 vmstorage 节点的耗时差异很大(超过 1~2 秒),可能表明资源饱和或存在硬件问题。
  5. 如果可行,建议增加更多 vmstorage 节点,以横向扩展 I/O 容量

数据获取缓慢/传输字节数高(单节点)

  1. 发送字节数较大,说明 VM 单节点正在进行大量 I/O
  2. 如果资源达到饱和,建议在 VictoriaMetrics 官方 Grafana 仪表板中检查资源使用情况。
  3. 建议检查 VM 单节点的磁盘 I/O 和 CPU
  4. 建议提高磁盘 I/O 限制
  5. 如果无法优化查询或查询的数据,建议切换到集群拓扑,以横向扩展 I/O 容量

汇总计算占主导(通常由扫描数百万个原始样本导致)

  1. 建议提高 vmselect 的 CPU 限制,以加快计算速度。
  2. 建议添加更具体的标签匹配器,以减少待处理的序列数量。
  3. 建议缩短时间范围,以减少原始样本量。
  4. 建议增大查询 step,以减少每条序列的数据点数量。
  5. 对于重复执行的仪表板查询,建议使用记录规则预先计算结果。

版本升级机会 如果 check_changelog.py 脚本发现了较新版本中的相关性能改进,请在“升级建议”报告部分中将升级列为附加建议。这是“仅使用单一模式”规则的唯一例外——无论选择了哪种瓶颈模式,都可以补充升级建议。仅纳入与观察到的瓶颈或追踪中涉及的组件直接相关的条目。

评论

支持 Markdown