Amazon CodeGuru Profilerを使ってみる

2021.03.15

What is Amazon CodeGuru?

Amazon CodeGuruとは、機械学習を活用してコードレビューを自動化し、
アプリケーションのパフォーマンスを最適化するためのサービスです。
図のように、CodeGuru ReviewerとCodeGuru Profilerで構成されています。

CodeGuru Reviewer?

Java/Pythonにおけるコード上の問題を検出し、
それらを修正するための推奨事項を提供してくれます。

機械学習、AWSとセキュリティのベストプラクティス、および何千ものオープンソースと Amazon リポジトリに対する何百万ものコードレビュー通して苦労して取得したレッスンを使用

GitHubやAWS CodeCommit 上にあるコードをCodeGuru に関連付けることで、
ソースコードに機械学習ベースの自動コードレビューをすることができます。
※本稿では使用しません

Amazon CodeGuru Profiler?

機械学習をベースとしたアプリケーションプロファイラを使用して、
稼働しているアプリケーションのパフォーマンスを測定し、コストが高いコード行を特定します。
また、アプリケーションのプロファイルデータを継続的に収集し、
よりよいパフォーマンスとなるための改善方法を含む推奨事項を教えてくれたり、
異常検出の機能も持っています。

ec2、fargate、lambda、さらにはオンプレミスで実行中の
あらゆるアプリケーションのパフォーマンスを最適化可能となっています。

本稿ではこのCodeGuru Profilerを試してみます。

Feature of CodeGuru Profiler

CodeGuru Profilerの主な特徴は下記。

  • 既存のアプリに対し容易にProfiler機能を組み込める
  • プロファイルしたデータを元にパフォーマンス向上のためのレコメンデーションを提供
  • 過去データと乖離がある場合、機械学習をベースとした異常検知をしてくれる
  • アプリに組み込むProfilerエージェントはフットプリントが小さい

Setting CodeGuru Profiler

では実際にCodeGuru Priofiler設定して組み込んでみます。
AWSが推奨する方法はJVMエージェントを使う方法なので、それでやってみましょう。

なお、CodeGuru ProfilerはAWS環境であればAmazon EC2、Amazon ECS、EKS、AWS Fargateか
AWS Lambdaで動作していればプロファイリングが可能です。
※今回はAWS fargateで確認しました

1. Codeguruプロファイリンググループの作成

※AWSアカウントやcli、権限は設定済みと仮定

まずはCLIでプロファイリンググループを作成します。(AWSコンソールからでもOK)。
jsonファイルにパラメータを記述して、CLIを実行します。

パラメータファイルであるsettings.jsonを作成。

{
    "profilingGroupName": "my-profiler-example"
}

awsコマンドでプロファイリンググループの作成。

aws codeguruprofiler create-profiling-group --cli-input-json file://settings.json --profile <your profile>
{
    "profilingGroup": {
        "agentOrchestrationConfig": {
            "profilingEnabled": true
        },
        "arn": "arn:aws:codeguru-profiler:ap-northeast-1:xxxxxx:profilingGroup/my-profiler-example",
        "computePlatform": "Default",
        "createdAt": "2021-03・・・",
        "name": "my-profiler-example",
        "tags": {},
        "updatedAt": "2021-03・・・"
    }
}

コマンド実行後、Codeguruのダッシュボードに指定したグループができてます。

2. agentのダウンロード/設定など

プロファイリンググループを作成したら、あとはjarを組み込んでアプリを起動するだけです。
AWSコンソールでダッシュボードをみると、
jarのダウンロードURLや起動方法が記述してるので、それを参考にしましょう。

jarをダウンロードしたら、↓みたいに起動すればOKです。

% java -javaagent:/path/your/codeguru-profiler-java-agent-standalone1.x.x.jar="profilingGroupName:<ProfilingGroupName>,heapSummaryEnabled:true" -jar YourApplication.jar

※アプリのMainクラスでエージェントを起動する方法もある

実際にCodeguruを稼働させている環境では、
対象アプリのDockerfileでjarをダウンロードし、
デプロイ時の起動オプションでjavaagentを指定しました。

3.アプリに対してアクセスし、プロファイル結果を確認

この状態でアプリを実行し、しばらくすると分析情報を
CodeGuruダッシュボードから確認することができるのですが、
私の場合、画面が真っ白になり何も表示されませんでした。
いろいろ試したところ、ブラウザのlangが日本語だと
表示されないことがわかったので、langを英語にしました。
もし同じような状況になった場合、ブラウザの言語情報を確認してみてください。

ダッシュボードではCPU時間、メモリ使用率、レイテンシーを確認することができます。

4.後片付け

使い終わったら、プロファイリンググループを無効化するか、
下記コマンドで削除しておきましょう。

% aws codeguruprofiler delete-profiling-group --cli-input-json file://settings.json --profile <your profile>

Frame Graph

ダッシュボードからVisualize CPUボタンをクリックすると、
Flame Graphを表示することができます。

これは、アプリのスタックトレースのサンプリングを集約したもので、
どのコードがCPU時間を使用しているか確認するために役立ちます。

上の図はFlame Graphのサンプルです。
この図からは下記のようなことがわかります。

  • main関数ではmethodFoo関数とmethodBar関数を呼び出している
  • methodBar関数はmain関数とmethodFoo関数からよびだされている
  • methodFoo関数のCPU時間は半分以上methodBar関数で消費されている
  • methodFoo関数自体もCPU時間を多少使っている(フレーム上にスペースがある)

こういった分析結果からボトルネックを特定し、性能改善の足がかりにします。
また、CPU以外にも、レイテンシーを確認するためのviewもあります。

Frame Graphやビューについてはこの資料にとても詳しくのっているので、参照してください。

Recomendation report

ダッシュボードからView Reportボタンをクリックすると、
プロファイリングデータを元に生成されたレコメンデーションレポートを表示します。
このレポートには、性能改善に役立つと思われるレコメンデーションと検知された異常について表示されます。

レコメンデーションは非効率的な処理や無駄なオブジェクト生成など、
CPUやメモリなどのリソースを無駄に消費するようなパターンに対して改善案が提示されます。
また、過去のプロファイリングデータと比べてあまりにも実測値の乖離が
大きい場合は異常として検知されます。
なお、この異常検知は機械学習をベースとしているので、
フィードバックすると精度向上にもつながるようです。

Summary

今回はAmazon CodeGuru Profilerについて紹介しました。
処理内容を適切に分析し、パフォーマンス向とインフラコストの削減に役立ててください。

References