[レポート] Lambda関数のパフォーマンスチューニング SVS224-R AWS Lambda function performance tuning #reinvent

AWS Lambda Power Tuningなる便利ツールがあるようです。ワークロードの特性とコスト/パフォーマンスのトレードオフを考慮してLambdaのパフォチューを行いましょう!!
2019.12.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CX事業本部@大阪の岩田です。 本エントリはSVS224-R AWS Lambda function performance tuning

のレポートとなります。

セッション情報

All AWS Lambda functions are not created equal. Learn the best practices for tuning memory, runtime, initialization, concurrency, and more, in a data-driven way, to squeeze every drop of performance out of Lambda functions. By the end of this session, you'll understand the key Lambda performance knobs you can turn to make the most of your functions for your workload.

レポート

Lambdaの基礎と最新のニュース

  • セッション聴講者が全員Lambdaを利用していたので、Lambdaの基礎については省略
  • 新たにProvisioned Concurrencyの設定が可能になった
  • 初期化処理完了済みのLambda実行環境をプールしておける機能
  • 5分程度でLambda実行環境の準備が可能
  • CloudFormationも対応済み
  • Application Auto Scallingを使うことで1~対象AWSアカウントのLambda同時実行数上限までLambda実行環境を事前準備することができる。
  • handler外に書いた初期化コードも自動的に実行される
  • これまでCloudWatch EventからLambdaを定期実行することで、コールドスタートを回避していたようなユースケースで利用できる

最適化のためのベストプラクティス

  • モノリシックな実装を避ける
    • 1つのLambdaに処理を詰め込むのはコールドスタートに悪影響
  • 依存関係を最適化し、不要なライブラリをロードしない
  • プロダクション環境向けにコードをminifyする
  • 共有するライブラリやオブジェクトは遅延読み込みする
  • オーケストレーションはLambda外で行う
  • リソースの割り当てを調整する
  • 処理すべきでないeventデータは早いタイミングで破棄する
  • リトライポリシーについて留意する
  • 同時実行数の制御について理解する

Lambdaへのメモリ割り当てについて

  • Lambdaにとってはメモリ = Power

  • Lambda実行環境が利用可能なCPUクロック周波数やNW帯域もメモリの割り当てに比例して大きくなっていく
  • メモリ割り当てを上げることでコストは高くなるが、CPUパワーが上がることでLambdaの実行時間が短くなり、結果的にコストが変わらない(もしくは安くなる)ということもある
  • 特にCPUバウンドな処理

AWS Lambda Power Tuning

  • Lambdaに最適なメモリ割り当て算出を支援するAWS Lambda Power Tuningというツールがある
  • SAR(Serverless Application Repository)からも利用可能
  • CI/CDパイプラインとの統合も用意
  • v1~v3のバージョンがある

AWS Lambda Power Tuningの利用例

  • 入力値のサンプル
    • メモリ割り当てのパターンを指定可能
    • ALLという指定も可能
    • どこに主軸を置いて最適化するか選択可能
    • スピード重視
    • コスト重視
    • バランス重視
    • 自動でLambdaのエイリアスをPublishすることも可能
    • CI/CDパイプラインでの利用が有効
  • 出力値のサンプル
    • 推奨されるメモリの設定値やコスト試算が確認できる
    • 分析結果を可視化したもの確認可能

現実世界における例

特に操作無し100ms以内に収まるちょっとしたデータ操作

  • メモリ1G程度が最適解になることが多い

CPUバウンドな処理(例えばnumpyによる行列の計算)

  • メモリ1530M程度まではメモリ割り当てに応じて処理時間が短くなる
  • 1530Mを超えたあたりから改善効果が小さくなる
  • メモリを増やすことで処理が高速化されるので、メモリ割り当てを増やしてもコストは大して増えない

メモリ1530M以上は...という話についてはメモリ割り当て1,792MBで1vCPU分のCPUパワーが使えるというLambdaの仕様と関連していそうです

Lambda では、構成されているメモリの量に比例して CPU パワーが直線的に割り当てられます。1,792 MB では、関数は 1 つのフル vCPU (1 秒あたりのクレジットの 1 vCPU 秒) に相当します

AWS Lambda 関数の設定

少し本筋からは逸れますが、メモリ割り当てとCPUパワーの関係については以下のブログも参考になりそうです。

How does proportional CPU allocation work with AWS Lambda?

CPUバウンドな処理(素数の計算)

  • 1536M程度が最適解になる
  • それ以上メモリ割り当てを増やしても早くならないし、コストが上がっていく

NWバウンドな処理(外部APIをコールするような処理)

  • 外部サーバー側がボトルネックになる
  • メモリ割り当てを増やしても大して効果はない

NWバウンドな処理(DynamoDBのクエリを3回実行)

  • 512MB程度で性能は頭打ちになる

NWバウンドな処理(S3から150MのファイルをDL)

  • 1024MBまでは性能が伸びていく
  • メモリ割り当てに比例してNW帯域が使えるようになるため

NWバウンドな処理(S3から150MのファイルをDL マルチスレッド版)

  • 2560MBを過ぎたあたりから、また性能が伸びる

こちらに関しても

Lambda では、構成されているメモリの量に比例して CPU パワーが直線的に割り当てられます。1,792 MB では、関数は 1 つのフル vCPU (1 秒あたりのクレジットの 1 vCPU 秒) に相当します

という仕様と関連しそうです。メモリ1,792 MB以上を割り当てたLambdaでは実装をマルチスレッド化することで、パフォーマンスが向上するパターンがありそうです。

セッションまとめ

  • Lambdaにとってはメモリ = Power
  • コールドスタートはProvisioned Concurrencyで回避する
  • リソースの割り当てはCI/CDで自動化する
  • 処理対象のワークロードがどのカテゴリに属するのか、コストとパフォーマンスのバランスを考慮する
  • コストとパフォーマンスのトレードオフを分析するためにAWS Lambda Power Tuningが利用できる

まとめ

Lambdaのメモリ割り当てを調整することでパフォーマンスが向上し、結果的にコストが安くなる可能性がある。という話は以前から認識していましたが、いざ実案件でやろうと思うと計測が面倒で、「大体1Gぐらいから性能上がりにくくなることが多いから1Gぐらいで良いだろう。」とか「特にパフォーマンス要件がシビアじゃない処理だし、デフォルトの128Mで良いか」みたいな選択をすることが多く、なかなか最適化された設定を実戦投入できていませんでした。

セッションで紹介されていたaws-lambda-power-tuningを使うと、計測の煩わしさ無しにLamdbaの設定を最適化できる可能性を感じました。まだ実際にaws-lambda-power-tuningを試せてないのですが、今後検証記事を書いていきたいと思います。