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. 04vmstorageごとの詳細を報告
  5. 05新しいVictoriaMetricsの変更履歴を確認
  6. 06ボトルネックに応じて改善案を選択

活用シーン

  1. 01遅いPromQLクエリの診断
  2. 02vmstorage間でクエリ段階を比較
  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 モードでは、クエリ処理に 2 つのコンポーネントが関与します。

  • vmselect — PromQL または MetricsQL クエリを受け付け、vmstorage ノードからデータを取得して計算を適用するクエリフロントエンド
  • vmstorage — 時系列データを保存し、RPC 経由で vmselect に提供します

Single-node モードでは、すべての処理を 1 つのプロセスで実行します。トレース構造は似ていますが、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 です。解析、時系列検索、ストレージからのデータ取得、ロールアップ計算、集約、レスポンス生成まで、クエリ実行パイプライン全体が記録されます。

トレースの分析方法

ステップ 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 のスクリプト出力を使用します)。 ルートノードから全体像を把握できます。以下を抽出してください。

  • エンドポイント:/api/v1/query(instant)または /api/v1/query_range(range)
  • クエリ:query= の後にある PromQL 式
  • 時間パラメーター:start=、end=、step=(range クエリの場合)
  • 結果数:末尾にある 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 に解決される箇所:

  • クラスターのトレースでは、rpc at vmstorage <addr> → rpc call search_v7() にラップされています。単一ノードでは、RPC ラッパーなしで直接表示されます
  • 主なメッセージ:
    • init series search
    • search TSIDs
    • search N indexDBs in parallel — インデックスデータベースの並列検索
    • search indexDB — 個々のインデックスパーティション
    • found N metric ids for filter=... — メトリック ID。vmstorage 内で一意な時系列識別子
    • found N TSIDs for N metricIDs — メトリック 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

データ取得 — 生データの取得:

  • クラスター: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 ノードを合計した概要
  • 単一ノード: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 を記録します。 クラスターのトレースでは、同じフェーズが vmstorage ノードごとに繰り返されます。概要には合計値を記録しつつ、ノード間の偏りを見つけられるよう、ノードごとの数値も記録します。

ステップ 4:ボトルネックを特定する

最も時間がかかったフェーズを特定し、具体的な理由を説明してください。 たとえば、「ロールアップで生のサンプルを 2 億 1,200 万件スキャンした」は有用ですが、「クエリが遅かった」では不十分です。

ステップ 5:推奨事項を作成する

推奨事項は、トレースで実際に確認できる内容のみに基づいてください。 クエリが高速で問題がなければ、そのように伝えてください。問題を作り上げてはいけません。

以下のアルゴリズムに従って推奨事項を選択してください。

  • ステップ 5a: 時間の内訳から、合計レイテンシの大部分(60%超)を占めるフェーズを 1 つ特定します。そのフェーズに対応する「推奨パターン」セクションのパターンを選びます。
  • ステップ 5b: そのパターンに記載された推奨事項のみを、記載された優先順位で使用してください。他のパターンから推奨事項を取り入れてはいけません。
  • ステップ 5c: 60%を超えるフェーズが 1 つもない場合は、寄与率が最も高いパターンを選び、副次的な要因にも言及します。ただし、複数のパターンの推奨事項を混ぜてはいけません。

レポート形式

## 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~2 秒を超える場合を除き、記載しないでください。
  • 所要時間には「Xm」「Xs」「Xms」の形式を使用してください(例:「123ms」)。60 秒を超える場合のみ分を、1000ms を超える場合は秒を、それより短い場合は ms を使用してください。
  • データ量には、読みやすい形式を使用してください(例:「268000000 bytes」ではなく「268 MB」)。サイズに応じて適切な単位(KB、MB、GB)を使用してください。
  • 所要時間は、推定して差し引きで求めず、トレースの duration_msec の値を直接使用してください。
  • クラスターのトレースでは、各 vmstorage ノードに同じフェーズ(インデックス検索、データスキャン)が現れます。要約ではこれらを合算し、ユーザーが偏りを確認できるよう、ノードごとの内訳も示してください。
  • トレースが大きすぎて一度に読み取れない場合は、まずトップレベルの構造を確認し、duration_msec に基づいて最も遅い分岐を特定してから、詳細を確認してください。
  • トレースには subquery または @ modifier の評価が含まれる場合があります。これらはネストされた eval フェーズとして扱ってください。
  • eval メッセージ内の mayCache=false は情報であり、問題ではありません。

推奨パターン

重要:パターンの選択ルール

  1. まず、時間の内訳からボトルネックに該当するパターンを以下から1つだけ特定してください。
  2. 選択したパターンの推奨事項のみを、記載されている優先順位に従って使用してください。
  3. 異なるパターンの推奨事項を混在させないでください。支配的なフェーズがレイテンシ全体の60%を超える場合、すべての推奨事項は必ずそのパターンのみから選んでください。
  4. 推奨事項が複数のパターンに記載されていても、その推奨事項がパターンに依存しないという意味ではありません。選択したパターンに記載されている場合にのみ使用してください。

トレースで実際に確認できる内容に基づき、優先順位順に推奨事項を提示してください。 以下に、一般的なパターンと対応するアドバイスを示します。

シリーズのカーディナリティが高い(マッチしたシリーズが多い)

  1. シリーズ数を減らすため、より具体的なラベルマッチャーを追加するよう提案します
  2. ダッシュボードのクエリであれば、記録ルールを使って事前集計するよう提案します
  3. 可能であれば、保存前にストリーム集約を使ってシリーズを事前集計するよう提案します
  4. マッチしたメトリクスのチャーンレートが高い場合は、時間範囲を狭めるよう提案します

大量の生サンプルをスキャンしている(samplesScanned が多い)

  1. samplesScanned の値が取得したサンプル数を大幅に上回る場合、クエリで [window] が短すぎるか、サブクエリが過剰に実行されています。
  2. rate()/irate()/increase() では、意味的に許容できる場合、[window] を短くするよう提案します
  3. シリーズごとのポイント数を減らすため、クエリのステップを大きくするよう提案します
  4. 時間範囲を狭めるよう提案します

インデックス検索が遅い(シリーズ検索が支配的)

  1. タグフィルターのキャッシュミスは初回クエリでは通常のことです。繰り返し実行するクエリは速くなるはずです
  2. 1日のパーティションあたりのメトリクス ID 数が多い場合、チャーンが多いか、カーディナリティの問題があることを示しています
  3. 可能であれば、より選択性の高いフィルターを使うよう提案します
  4. 可能であれば、vmstorage ノードのメモリを増やすよう提案します

データ取得が遅い/転送バイト数が多い(クラスター)

  1. 送信バイト数が多い場合、vmstorage で大量の I/O が発生していることを示しています
  2. リソースの飽和が疑われる場合は、VictoriaMetrics の公式 Grafana ダッシュボードでリソース使用状況を確認するよう提案します。
  3. vmstorage のディスク I/O とネットワーク帯域幅を確認するよう提案します
  4. 複数の vmstorage ノード間で処理時間に大きなばらつき(1~2 秒以上)がある場合、リソースの飽和またはハードウェアの問題を示している可能性があります。
  5. 可能であれば、I/O 容量を水平スケーリングするために vmstorage ノードを追加するよう提案します

データ取得が遅い/転送バイト数が多い(単一ノード)

  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 スクリプトで新しいバージョンに関連するパフォーマンス改善が見つかった場合は、「アップグレードの推奨事項」レポートセクションに追加の推奨事項として記載してください。これは「単一パターンのみ」のルールに対する唯一の例外です。選択したボトルネックのパターンに関係なく、アップグレードの推奨事項を補足として追加できます。観測されたボトルネックまたはトレースに含まれるコンポーネントに直接関連する項目のみを含めてください。

コメント