performance-engineer について
アプリケーションやインフラのボトルネック調査に取り組む開発者や運用担当者向けのパフォーマンスエンジニアリングスキルです。CPU 分析からフロントエンドの応答性改善まで、プロファイリング、負荷テスト、トレース、Linux チューニングを扱います。
主な機能
- 01CPU とメモリのプロファイリング
- 02フレームグラフ分析
- 03負荷テストの戦略
- 04eBPF とカーネルの調整
- 05分散トレースとレイテンシ分析
- 06フロントエンドの応答性改善
活用シーン
- 01本番環境のレイテンシ急増の調査
- 02アプリケーションの CPU ホットスポット特定
- 03トラフィック増加に備えた容量の見積もり
- 04マイクロサービス間のレイテンシ診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ 404kidwiz/ claude-supercode-skills --skill performance-engineerインストール後、Claude Code で/performance-engineerを入力して読み込まれたか確認します。
詳細
パフォーマンスエンジニア
目的
eBPF と Flamegraphs を使用した詳細なパフォーマンス分析、負荷テスト、カーネルレベルのチューニングを専門とし、システムの最適化とプロファイリングに関する専門知識を提供します。アプリケーションとインフラストラクチャのパフォーマンスボトルネックを特定し、解消します。
使用する場面
- 高レイテンシ(P99 の急上昇)や低スループットを調査する場合
- CPU/メモリのプロファイル(Flamegraphs)を分析する場合
- 負荷テスト(K6、Gatling、Locust)を実施する場合
- Linux カーネルのパラメーター(sysctl)をチューニングする場合
- 継続的プロファイリング(Parca、Pyroscope)を導入する場合
- 「自分のマシンでは動くのに、本番環境では遅い」という問題をデバッグする場合
2. 判断フレームワーク
プロファイリング戦略
What is the bottleneck?
│
├─ **CPU High?**
│ ├─ User Space? → **Language Profiler** (pprof, async-profiler)
│ └─ Kernel Space? → **perf / eBPF** (System calls, Context switches)
│
├─ **Memory High?**
│ ├─ Leak? → **Heap Dump Analysis** (Eclipse MAT, heaptrack)
│ └─ Fragmentation? → **Allocator tuning** (jemalloc, tcmalloc)
│
├─ **I/O Wait?**
│ ├─ Disk? → **iostat / biotop**
│ └─ Network? → **tcpdump / Wireshark**
│
└─ **Latency (Wait Time)?**
└─ Distributed? → **Tracing** (OpenTelemetry, Jaeger)
負荷テストツール
| ツール | 言語 | 最適な用途 |
|---|---|---|
| K6 | JS | 開発者に使いやすく、CI/CD と統合できます。 |
| Gatling | Scala/Java | 高い同時実行性、複雑なシナリオ。 |
| Locust | Python | 迅速なプロトタイピング、コードベースのテスト。 |
| Wrk2 | C | HTTP スループットの直接的なベンチマーク(シンプル)。 |
最適化の優先順位
- アルゴリズム: O(n^2) → O(n log n)。最大の改善効果が得られます。
- アーキテクチャ: キャッシュ、非同期処理。
- コード/言語: メモリ割り当て、ループ展開。
- システム/カーネル: TCP スタックのチューニング、CPU アフィニティ。
注意すべき兆候 → database-optimizer にエスカレーション:
- 「パフォーマンスが遅い」原因が、インデックスのない単一の SQL クエリであることが判明した場合
- データベースのロックやデッドロックにより、アプリケーションが停止している場合
- DB サーバーでディスク I/O が飽和している場合
3. 主なワークフロー
ワークフロー 1:Flamegraphs を使った CPU プロファイリング
目標: CPU の 80% を消費している関数を特定します。
手順:
-
プロファイルを取得(Linux perf)
# 99Hz で 30 秒間スタックトレースを記録 perf record -F 99 -a -g -- sleep 30 -
Flamegraph を生成
perf script > out.perf ./stackcollapse-perf.pl out.perf > out.folded ./flamegraph.pl out.folded > profile.svg -
分析
- ブラウザーで
profile.svgを開きます。 - 幅の広いタワー(時間を消費している関数)を探します。
- 例:
json_parseの幅が 40% → JSON 処理を最適化します。
- ブラウザーで
ワークフロー 3:Interaction to Next Paint(INP)
目標: フロントエンドの応答性を改善します(Core Web Vital)。
手順:
-
測定
- Chrome DevTools の Performance タブを使用します。
- 「Long Tasks」(50ms を超える赤いブロック)を探します。
-
特定
- ハイドレーションが原因でしょうか? イベントハンドラーでしょうか?
- 例: クリックハンドラーが同期的なレイアウトの再計算を強制しています。
-
最適化
- メインスレッドに処理を譲る:
await new Promise(r => setTimeout(r, 0))またはscheduler.postTask()。 - Web Workers: 負荷の高いロジックを別スレッドに移します。
- メインスレッドに処理を譲る:
ワークフロー 5:Interaction to Next Paint(INP)の最適化
目標: React ボタンの「クリック時の遅延」(INP > 200ms)を解消します。
手順:
-
操作を特定
- React DevTools Profiler(Interaction Tracing)を使用します。
clickハンドラーの実行時間を確認します。
-
長時間タスクを分割
async function handleClick() { // 1. UI Update (Immediate) setLoading(true); // 2. Yield to main thread to let browser paint await new Promise(r => setTimeout(r, 0)); // 3. Heavy Logic await heavyCalculation(); setLoading(false); } -
確認
Web Vitals拡張機能を使用します。INP が 200ms 未満に下がるか確認します。
5. アンチパターンと注意点
❌ アンチパターン 1:時期尚早な最適化
例:
- 計測せずに、「速いから」という理由で、読みやすい
map()を複雑なforループに置き換える。
うまくいかない理由:
- 開発時間を無駄にします。
- コードが読みにくくなります。
- I/O と比べると、通常は影響がごくわずかです。
適切な方法:
- まず計測: プロファイラーで特定したホットパスだけを最適化します。
❌ アンチパターン 2:「localhost」と本番環境の比較テスト
具体例:
- 「自分の MacBook では 10k req/s を処理できます。」
問題点:
- ネットワーク遅延(localhost では 0ms)。
- データベースのデータセットサイズ(ローカルではごく小規模)。
- クラウドの制限(CPU クレジット、I/O バースト)。
正しい方法:
- 本番環境と同等のキャパシティ(または縮小した比率)を備えたステージング環境でテストします。
❌ アンチパターン 3:テールレイテンシ(平均値)の無視
具体例:
- 「平均レイテンシは 200ms なので問題ありません。」
問題点:
- P99 が 10 秒に達する場合があります。ユーザーの 1% が苦しんでいます。
- マイクロサービスでは、テールレイテンシが積み重なります。
正しい方法:
- 常に P50、P95、P99 を測定します。P99 の最適化を優先します。
例
例 1:フレームグラフを使用した CPU パフォーマンスの最適化
シナリオ: 本番 API の CPU 使用率が 80% に達し、レイテンシの急増が発生しています。
調査方法:
- プロファイルの収集:perf を使用して CPU のスタックトレースを取得
- フレームグラフの生成:CPU 使用率を可視化
- 分析:CPU を最も消費しているホット関数を特定
- 最適化:上位 3 つの関数を対象に実施
主な調査結果:
| 関数 | CPU % | 最適化の対応 |
|---|---|---|
| json_serialize | 35% | バイナリ形式に切り替え |
| crypto_hash | 25% | ハッシュ処理をバッチ化 |
| regex_match | 20% | パターンを事前コンパイル |
結果:
- CPU 使用率:80% → 35%
- P99 レイテンシ:1.2s → 150ms
- スループット:500 RPS → 2,000 RPS
例 2:マイクロサービスのレイテンシに対する分散トレーシング
シナリオ: 15 個のサービスで構成される分散システムで、エンドツーエンドのレイテンシに問題が発生しています。
調査方法:
- トレースの収集:OpenTelemetry コレクターをデプロイ
- レイテンシ分析:レイテンシへの寄与が最も大きいサービスを特定
- 依存関係の分析:サービス間の依存関係とデータフローをマッピング
- 根本原因:データベース接続プールの枯渇
トレース分析:
Service A (50ms) → Service B (200ms) → Service C (500ms) → Database (1s)
↑
Connection pool exhaustion
解決策:
- 接続プールのサイズを拡大
- クエリを最適化
- 負荷の高いクエリ用に読み取りレプリカを追加
結果:
- エンドツーエンドの P99:2.5s → 300ms
- データベースの CPU 使用率:95% → 60%
- エラー率:5% → 0.1%
例 3:キャパシティプランニングのための負荷テスト
シナリオ: E コマースプラットフォームで、ブラックフライデーのトラフィック(通常の 10 倍)に備えています。
負荷テストの方法:
- テスト設計:現実的なユーザージャーニーのシナリオを作成
- テスト実行:目標負荷まで段階的に引き上げ
- ボトルネックの特定:限界点を発見
- キャパシティプランニング:必要なリソースを決定
負荷テストの結果:
| 仮想ユーザー数 | RPS | P95 レイテンシ | エラー率 |
|---|---|---|---|
| 1,000 | 500 | 150ms | 0.1% |
| 5,000 | 2,400 | 280ms | 0.3% |
| 10,000 | 4,800 | 550ms | 1.2% |
| 15,000 | 6,200 | 1.2s | 5.8% |
キャパシティに関する推奨事項:
- 同時ユーザー数を 12,000 にスケール
- アプリケーションサーバーをさらに 3 台追加
- データベースの読み取りレプリカを 5 台に増加
- 10,000 RPS でレート制限を実装
ベストプラクティス
プロファイリングと分析
- まず測定する:最適化の前に必ずプロファイリングを実施します
- 包括的なカバレッジ:CPU、メモリ、I/O、ネットワークを分析します
- 本番環境で安全に実施:本番環境ではオーバーヘッドの小さいプロファイリングを使用します
- 定期的なベースライン:比較用のパフォーマンスベースラインを確立します
負荷テスト
- 現実的なシナリオ:実際のユーザーの行動やワークフローをモデル化します
- 段階的な引き上げ:低い負荷から開始し、徐々に増やします
- ボトルネックの特定:制約要因を体系的に発見します
- 再現性:一貫性のあるテスト環境を維持します
パフォーマンス最適化
- まずアルゴリズムを最適化:細かな最適化より先にアルゴリズムを最適化します
- キャッシュ戦略:適切なキャッシュレイヤーを実装します
- データベースの最適化:インデックス、クエリ、接続プーリングを最適化します
- リソース管理:効率的な割り当てとプーリングを行います
モニタリングと可観測性
- 包括的なメトリクス:CPU、メモリ、ディスク、ネットワーク、アプリケーション
- 分散トレーシング:マイクロサービス全体をエンドツーエンドで可視化
- アラート:パフォーマンス低下を事前に特定
- ダッシュボード:システムの健全性をリアルタイムで可視化
品質チェックリスト
プロファイリング:
- シンボル: 正確なスタックトレースを取得するためのデバッグシンボルが利用可能である。
- オーバーヘッド: プロファイラーのオーバーヘッドを確認済みである(本番環境では 1~2% 未満)。
- 範囲: CPU 時間と実時間の両方を分析している。
- コンテキスト: プロファイルにリクエストのライフサイクル全体が含まれている。
負荷テスト:
- シナリオ: 現実的なユーザーの行動を再現している(単一のエンドポイントにアクセスするだけではない)。
- ウォームアップ: 測定前にシステムをウォームアップしている(JIT/キャッシュ)。
- ボトルネック: 制限要因(CPU、DB、帯域幅)を特定している。
- 再現性: テストを一貫して実行できる。
最適化:
- 検証: 改善を確認するため、修正後にベンチマークを実行している。
- リグレッション: 最適化によって機能が損なわれていないことを確認している。
- ドキュメント: 最適化を行った理由を記録している。
- モニタリング: 最適化の影響を追跡するメトリクスを追加している。