Rust CPU プロファイリング:OpenResty XRay で Sled の最もホットなコードパスを特定
Rust 製の組み込み型 KV データベース「Sled」をベースにした社内キャッシュサービスが、100% を超える CPU を消費していました。OpenResty XRay による Rust CPU プロファイリングで、その負荷を 2 つのホットなコードパス——sled::tree::Tree::insert と get_inner(CPU 時間の約 40%)——まで追跡し、該当するソースコードの行まで特定しました。コードの変更も再コンパイルも一切不要です。
本チュートリアルでは、この分析の全過程を段階的に解説します。以下に示すホットなコードパスは、OpenResty XRay が Rust 言語レベルの CPU フレームグラフを自動的に分析・解釈して得たものです。
問題:Sled ベースのキャッシュサービスが 100% 超の CPU を消費
Sled は Rust で書かれた組み込み型 KV データベースであり、社内キャッシュサービスはその上に構築されています。top で確認すると、このプロセスの CPU 使用率は 100% を超え続けていました。
Guided Analysis による実行中の Rust プロセスのプロファイリング
OpenResty XRay を使用して、コードに手を加えていないこのプロセスを検査します。コード変更や再コンパイルなしに、リアルタイムで分析して原因を特定できます。この種の分析の実行時オーバーヘッドは非常に小さく、Rust アプリケーションに対する OpenResty XRay の性能影響の実測記事で定量的に測定しています。
OpenResty XRay の Web コンソールを開き、対象マシンが正しいことを確認した上で、「Guided Analysis」ページに移動します。ここでは、診断可能な問題の種類が一覧表示されます。
「High CPU Usage」を選択し、先ほどの Sled アプリケーションと、100% 超の CPU リソースを消費しているプロセス——top で確認したもの——を選択します。
アプリケーションタイプはデフォルトで Rust となっており、言語レベルもここでは「Rust」のみです。最大分析時間はデフォルトの 300 秒のままで、分析を開始します。システムは複数ラウンドの分析を継続的に実行しますが、この例では最初のラウンドが完了すれば十分なため、分析を停止すると分析レポートが自動生成されます。
Rust CPU フレームグラフの解読:最もホットなコードパス
レポートには、CPU 時間を最も消費している Rust コードパス(#1)が表示されます。
最初の関数 sled::tree::Tree::insert は、Sled でデータを挿入するために使用されます。
「More」をクリックして詳細を表示します。
上記のホットなコードパスは、以下の Rust 言語レベルの CPU フレームグラフから自動的に導き出されたものです。
以下は、レポートが本問題に対して示すより詳細な説明と提案です。Explanation セクションでは insert とその呼び出し連鎖上の各関数を解説し、Suggestions セクションではバッチ書き込み(sled::Batch)、並行化、パラメータチューニングといった最適化の方向性を提示しています。
このアイコンをクリックしてフレームグラフを拡大します。
insert 関数のフレームをクリックして詳細を表示します。
左側では view_for_key 関数が大きな割合を占めています。これは Sled ライブラリ内で、指定されたキーのスナップショットビューを取得する関数です。
右側の pagecache は、ページ単位でデータを管理する Sled のコンポーネントです。書き込まれたデータは最初に pagecache のメモリページに保存され、バッチが満杯になるとディスクにフラッシュして永続化されます。
さらに拡大します。
Glibc の realloc 関数が見えてきます。このワークロードでは、libc のメモリ割り当て関数がホットになっています。
フレームグラフから Sled のソースコードへ
ターミナルで find コマンドを使用し、cargo キャッシュ内の Sled ライブラリのソースコードディレクトリを探します。
見つかったディレクトリをコピーし、Sled のソースコードディレクトリに移動します。
フレームグラフに戻り、insert 関数の緑色の枠にマウスカーソルを合わせると、ツールチップにこの関数のソースファイル名が表示されます。
ツールチップに表示されるソースコードの行番号は 164 です。
このアイコンをクリックして、この関数のソースファイルパスをコピーします。
お好みのエディタでソースファイルを開き、先ほどコピーしたパスを貼り付けます(ここでは vim を使用しています)。
OpenResty XRay が示した 164 行目にジャンプします。
この行は insert 関数の内部にあります。
2 番目にホットなコードパス:get_inner と view_for_key
次に、2 番目のコードパスを確認します。2 番目にホットなコードパスは、CPU 時間の約 40% を消費しています。
先頭の関数呼び出し get_inner は、Sled でデータを検索する関数です。
get 関数はライブラリがユーザーに公開しているデータ取得インターフェースで、内部で get_inner を呼び出しています。
「More」をクリックして詳細を表示します。
フレームグラフを拡大し、get_inner 関数呼び出しの詳細を確認します。
さらに get_inner を拡大します。
get_inner 関数内の CPU 時間の大部分も、先ほどの view_for_key 関数に占められていることがわかります。
sled::lru::Lru::accessed 関数は、Rust の Sled ライブラリで LRU キャッシュ内のアイテムのアクセス状態を更新し、追い出しが必要なページ ID のリストを返すために使用されます。
自動生成される Rust CPU 分析レポート
OpenResty XRay は、稼働中のプロセスを自動的に監視して分析レポートを表示することもできます。
「Insights」ページに切り替えます。
「Insights」ページでは日次および週次のレポートを確認できるため、必ずしも「Guided Analysis」機能を使う必要はありません。
もっとも、「Guided Analysis」はアプリケーションの開発やデモンストレーションには非常に有用です。Insights の日次レポートでは、このプロセスの CPU 使用率(最小 102%、平均 107%、最大 113%)と、割合順に並んだ最もホットな Rust コードパスを確認できます。
CPU 時間の分析に加えて、OpenResty XRay は同じ非侵入型の方式で、Rust プログラムのパニックの追跡や、Rust アプリケーションの高ディスク I/O の診断も行えます。
よくある質問
コードを変更せずに Rust プログラムの CPU 使用率をプロファイリングするには?
動的トレーシングに基づく非侵入型のプロファイラを使用します。OpenResty XRay は、実行中の、手を加えていない Rust プロセスを直接分析します。Guided Analysis 機能で対象プロセスを選択すると、プロセスをサンプリングして Rust 言語レベルの CPU フレームグラフを生成します。再コンパイルも、対象プロセスへの計装も不要です。
どの Rust 関数が最も CPU を消費しているかを特定するには?
プロセスをサンプリングして Rust 言語レベルの CPU フレームグラフを取得し、OpenResty XRay にフレームグラフから最もホットなコードパスを自動的に推論させます。フレームグラフを手作業で読み解く必要はありません。本記事の Sled のケースでは、sled::tree::Tree::insert が最もホットなパスとして報告され、該当するソースコードの行番号(164 行目)まで示されました。
Sled ベースのサービスが 100% 超の CPU を消費していたのはなぜ?
このケースでは、CPU 時間は 2 つのパスに集中していました。1 つは sled::tree::Tree::insert によるデータ挿入で、view_for_key と pagecache への書き込みが大半を占め、Glibc の realloc メモリ割り当て関数もホットになっていました。もう 1 つは get_inner によるデータ検索で、CPU 時間の約 40% を消費しており、こちらも主に view_for_key に費やされていました。
OpenResty XRay について
OpenResty XRay は動的トレーシング製品であり、実行中のアプリケーションを自動的に分析して、パフォーマンスの問題、動作の問題、セキュリティの脆弱性を解決し、実行可能な提案を提供いたします。基盤となる実装において、OpenResty XRay は弊社の Y 言語によって駆動され、Stap+、eBPF+、GDB、ODB など、様々な環境下で複数の異なるランタイムをサポートしております。
著者について
章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。
章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay(動的トレーシング技術を利用した非侵入型の障害分析および排除ツール)と OpenResty Edge(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJIT、GDB、SystemTap、LLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。
翻訳
英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!





















































