Stackdriver Profiler(Cloud Profiler)を使ってKubernetes上のサーバー動的解析を行う
本記事
本記事ではKubernetesにStackdriver Profile(現時点ではBeta版)を使ってみて、自分のコードの動的解析を行ってみます。
それを通してStackdriver ProfileのGUIの操作方法などを習得したいと思います。
Stackdriver Profilerのデータ収集
HeapとThreadメトリクスを除いて一分間に1つのサービスが一回、収集され、10秒間のデータを取得する。
10個のサービスがあれば10分の間で1つずつ収集されることになる。
Stackdriver Profilerのサポート状況
執筆段階では以下のようなサポート状況でした。
メトリクス
Time メトリクス
項目 | 説明 | わかること |
---|---|---|
CPU Time | コードを実行するのに使ったCPU時間。待ち時間は含まれない。 | 関数を実行するのにかかった時間。 |
Wall Time | コードを実行するのに使った時間。待ち時間は含まれる。 | 関数を呼び出して、関数から出るまでの時間。 |
この二つを比較して
- CPU TimeがWall Timeよりかなり短い -> 待ち時間が長いのかも
- CPU TimeがWall Timeほぼ同じ -> その関数はCPUに負荷をかけているかも
現時点ではjava
しかすることができない。
Heap メトリクス
オブジェクトや関数を使うと、それはメモリを使います。そのメトリクスを取得します。
項目 | 説明 | わかること |
---|---|---|
Heap Consuption | プログラムのヒープに置いてあるデータ。 | 関数を実行するのにかかった時間。 |
Heap Allocation | プログラムのヒープに配置されたデータ。使っていないメモリも含まれる。 | 関数を呼び出して、関数から出るまでの時間。 |
Thread メトリクス
スレッドリークなどを検出するために使用できるメトリクス。
Contention メトリクス
マルチスレッドアプリケーションでは、共有リソースにアクセス待ちの時間が重要になってくるので、それを監視できるメトリクスです。
インストール方法
Cloud Profiler APIを有効化します
gcloud services enable cloudprofiler.googleapis.com
Profilerを使ったGoアプリケーションのデプロイ
以下のようにGolangアプリケーションに挟みます。
import ( "cloud.google.com/go/profiler" ) func main() { // Profiler initialization, best done as early as possible. if err := profiler.Start(profiler.Config{ Service: "myservice", ServiceVersion: "1.0.0", // ProjectID must be set if not running on GCP. // ProjectID: "my-project", }); err != nil { // TODO: Handle error. } }
これをKubernetesクラスタにデプロイします。
Locutsでリクエストを流す
Locustをホストしているクラスタからリクエストを流します。
100QPSになるくらいに設定しています。
GUIで確認する
GolangサーバーのProfile
GolangのEchoサーバーを使用しています。
以下のような項目を知ることができます。
CPU時間
Heap
Heap Allocation
Thread
まとめ
このようにStackdriver Profilerでプロファイルを取得することができました。
特に、フレームワークやライブラリに併せて自分の定義した関数などのプロファイルも取得できるので、パフォーマンスチューニングやメモリリークについて調査することができるいいツールだと思った。