このチュートリアルでは、OpenResty XRay を使用して Prometheus アプリケーション内で最も CPU を消費する Go(golang)コードパスを特定する方法を段階的にご説明いたします。これらのコードパスは最も多くの CPU 時間を消費し、Prometheus アプリケーションのパフォーマンスに重大な影響を与えています。

問題:高 CPU 使用率

このチュートリアルでは、Prometheus アプリケーション内で最も CPU を消費する Go コードパスを特定する方法を説明します。このアプリケーションは Go でコンパイルされています。

まず、top コマンドを実行して対象プロセスの CPU 使用状況を確認します。

Screenshot

この Prometheus プロセスが CPU リソースの 160% を消費していることがわかります。

Screenshot

ps コマンドを実行してこのプロセスの詳細を確認します。

Screenshot

この Prometheus バイナリ実行ファイルは Linux ディストリビューションに付属のものです。

Screenshot

CPU 使用率が最も高い Go コードパスを特定

OpenResty XRay を使用して、この未修正のプロセスを検査することができます。システムはリアルタイムで分析を行い、原因を特定します。

ブラウザで OpenResty XRay の Web コンソールを開きます。

Screenshot

現在分析中のマシンが正しいことを確認してください。

Screenshot

正しくない場合は、リストから再選択することができます。

Screenshot

「Guided Analysis」ページに移動します。

Screenshot

ここでは、システムが分析可能な様々な種類の問題を確認できます。

Screenshot

「High CPU usage」を選択します。

Screenshot

「Next」をクリックします。

Screenshot

先ほどの Go アプリケーションを選択します。

Screenshot

125% 以上の CPU を消費しているプロセスを選択します。これは先ほど top で確認したものです。

Screenshot

アプリケーションのタイプが正しいことを確認します。

Screenshot

通常、デフォルト値が正しいです。ここでの言語レベルは「Go」のみとなっています。

Screenshot

最長分析時間を設定することも可能です。ここではデフォルトの 300 秒のままにします。

Screenshot

分析を開始します。

Screenshot

システムの分析は継続的に複数回実行します。現在、初回の分析を実行中です。

Screenshot

初回の分析が完了し、現在 2 回目のラウンドに入っております。この例では、1 回の分析で十分です。

Screenshot

分析を停止します。

Screenshot

自動生成された分析レポートが表示されます。

Screenshot

これが分析対象の問題タイプ、「CPU」です。

Screenshot

Go のガベージコレクションが CPU 時間の 99% 以上を消費していることが確認できます。

スクリーンショット

例えば、このガベージコレクションを実行している Go コードパスが CPU 時間の 21% 以上を占めています。

スクリーンショット

scanobject は Go 言語のランタイム関数で、ガベージコレクションの作業を担当します。ヒープメモリ内で GC オブジェクトを探し、それらがアクセスできるオブジェクトをすべてマークします。

スクリーンショット

gcDrain 関数は、ワークキュー内の GC オブジェクトをすべてマークして除去する役割を果たします。

スクリーンショット

多数の GC オブジェクトを急速に割り当てると、GC のオーバーヘッドが非常に高くなります。そのため、レポートではオブジェクトを最も多く、最も速く割り当てている Go コードパスが示されています。

スクリーンショット

最も多くの GC オブジェクトを割り当てているこの Go コードパスを見てみましょう。

スクリーンショット

loadWAL 関数は、Prometheus の 先行書き込みログからデータをロードします。

スクリーンショット

Series 関数は、バッファからタイムシリーズデータをデコードし、指定されたスライスに追加します。

スクリーンショット

slicebytetostring 関数は、バイトスライスを文字列に変換します。

スクリーンショット

「More」をクリックすると、さらに詳細が表示されます。

スクリーンショット

このコードパスは、Go GC オブジェクト割り当てのフレームグラフから自動的に導き出されたものです。

スクリーンショット

以下は、現在の問題についてのより詳細な説明と提案です。

スクリーンショット

loadWAL 関数について言及しています。

スクリーンショット

この関数は先行書き込みログからデータをロードします。

スクリーンショット

また、Series 関数についても言及しています。

スクリーンショット

そして slicebytetostring 関数についても触れています。

スクリーンショット

先ほどのコードパスに戻りましょう。loadWAL 関数の緑色のボックスにマウスを置いてください。

スクリーンショット

この関数のソースファイル名が表示されます。ツールチップにはファイルの完全なパスも表示されています。

スクリーンショット

ソースコードの行番号は 141 です。

スクリーンショット

このアイコンをクリックすると、関数の完全な Go ソースファイルパスがコピーされます。

スクリーンショット

vim エディタを使用してソースファイルを開き、このファイル内の golang コードを確認します。

スクリーンショット

OpenResty XRay が提案したように、141 行目に注目してください。

スクリーンショット

dec.Series 関数は、1 つのレコードから一連のタイムシリーズをデコードします。

スクリーンショット

ステータスバーでは、このコード行が先ほどのレポートで言及されていた通り、loadWAL 関数内にあることが確認できます。

スクリーンショット

Prometheus の TSDB は、最新のデータを管理するためにメモリ内シリーズを作成します。このコードパスで新しく割り当てられた GC オブジェクトの数は、新規割り当て総数の 19% を超えています。

スクリーンショット

ここでは、新しい GC オブジェクトの動的割り当て操作が CPU 時間の約 11% を占めていることがわかります。これはガベージコレクタの負担を増やすだけでなく、それ自体も大量の CPU リソースを消費しています。

Screenshot

完全自動化された分析とレポート

OpenResty XRay は、オンラインプロセスを自動的に監視し、分析レポートを表示することもできます。「Insights」ページに切り替えます。

Screenshot

「Insights」ページでは、日次および週次のレポートを確認することができます。

Screenshot

したがって、「Guided Analysis」機能を必ずしも使用する必要はありません。もちろん、「Guided Analysis」はアプリケーションの開発やデモンストレーションに非常に有用です。

Screenshot

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 XRay(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJITGDBSystemTapLLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。

翻訳

英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!