サーバレス時代の必須技術、AWS Lambdaを知ろう

2024.03.21
マルチクラウド 技術 AWS クラウド活用 パフォーマンス改善
サーバレス時代の必須技術、AWS Lambdaを知ろう

はじめに

こんにちは。技術本部 アーキテクチャ&テクノロジー部の髙橋 洋樹です。少し春めいてきましたが皆様いかがお過ごしでしょうか。今回初めて私のブログを読んでくださる方に向けて、自己紹介をさせてもらいます。私が所属する部署は全社の開発技術力の強化をミッションとしており、私はその中でもパブリッククラウドに関する全社共通基盤の企画・運用、アーキテクトの育成、ガイドラインの策定などを推進しています。皆様がAWSをより深く活用するためのノウハウを定期的に発信していきたいと思いますので、よろしくお願いします。
なお、以前掲載した、AWSのコスト最適化に関するブログ(全4回)も、ご興味あればぜひ読んでみてください!

さて早速ですが、最近AWS Lambdaの性能が課題となる相談を耳にすることが増えてきた気がします。これまでLambdaのパフォーマンスまで意識したことがなかったと思い、同じようにAWS Lambdaをなんとなく使用しているエンジニアの方に向けて、私自身の学びを基礎も含めて共有していければと思いました。そこで、今回はAWS Lambdaの基礎について、次回・次々回ではLambdaのパフォーマンス改善についてブログを投稿していきたいと思います。

AWS Lambdaについておさらい

AWS Lambdaのパフォーマンスを適切に改善していくためには、そもそもの仕組みを理解することが重要です。まずはAWS Lambdaについておさらいをしておきましょう。

1. AWS Lambdaとは

AWS LambdaはAWSが提供しているサーバレスコンピューティングのサービスです。利用者はプログラムのコードを用意し、アップロードするだけで処理を実行することができます。差別化要因にならないインフラストラクチャ層の管理をAWS層に任せて、エンジニアの皆様がコード作成に集中できるようになるのが最大のメリットです。

2. ハンドラー:Lambda関数の処理を定義するメソッド

Lambda関数の作成にあたって、利用者は関数名、ランタイム(言語とバージョンの組み合わせ。Python 3.12など)、CPUアーキテクチャ(x86_64など)を指定してコードを書いていきます。コード内でLambda関数が呼び出されたときに毎回実行する処理を定義しているメソッドを「ハンドラー」と言います。以下にPythonのLambda関数のサンプルコードを示します。

画面:Lambda関数のサンプルコード

画面:Lambda関数のサンプルコード

このサンプルコード中の「lambda_handler」の関数がハンドラーです。性能的な話をすると仮にLambda関数の実行が毎回遅い場合、このハンドラー内で何か重い処理をしていないかをまずは確認していく流れになります。なお、ハンドラーとする関数の引数は固定ですが、名称は任意に指定可能です。

ハンドラーには「15分」という変えることのできない実行時間の上限制限が存在し、これがLambda関数を利用するかどうかを決める上で重要な制限となっています。そのため、15分以上かかる処理を実行したい場合には、Lambda関数を分割してAWS Step Functionsでつなぐ、もしくは、基盤としてAWS LambdaではなくAWS Fargateを使うなど、別の選択肢を検討する必要がありますので注意してください。

3. 実行トリガー:Lambda関数の呼び出され方

コードを記述したら、いよいよLambda関数を呼び出して実行していきます。呼び出す方法は複数あります。例えばAWS CLI/SDKでコマンドを実行したり、Amazon API Gatewayと連携させてhttpリクエストを発行したり、Amazon EventBridgeと連携させてスケジュールを設定するなどです。さらに、その先として意識したいことが、呼び出し方が同期なのか非同期なのか、またはポーリングなのかです(下図参照)。

Lambdaの呼び出し方

Lambdaの呼び出し方

同期呼び出しは、ハンドラーの終了を待ってクライアントにレスポンスを返す方式です。
一方で、非同期呼び出しはイベントがLambda内部のキューに格納された時点でクライアントにレスポンスを返す方式です。キューに格納されたイベントは順次ハンドラーによって処理されます。また、ストリームはLambda自身がAmazon Kinesis Data StreamsやAmazon DynamoDBをポーリングし、ハンドラーを実行する方式です。

どの呼び出し方になるかはLambda関数の連携する先のAWSサービスによって(AWS CLI/SDKの場合はオプションによって)異なります。種類によって必要な実装や設定が異なってくるので留意が必要です。

4. ライフサイクル:Lambda関数の一生

さて、これまではLambdaの概要と、Lambda関数のハンドラーと実行トリガーについて説明してきました。では次に、呼び出されたLambda関数が内部的にどのように起動し終了していくのか、つまりライフサイクルをおさらいしておきましょう。

Lambda関数のライフサイクルは大きくINIT、INVOKE、SHUTDOWNというフェーズで構成されています。

出典:Lambda実行環境

出典:Lambda実行環境

まずINITフェーズについてですが、ここではハンドラーを呼び出すための環境の準備をします。具体的には以下の処理が実施されます。

  1. 物理サーバにLambdaの実行環境(軽量仮想マシン)を立ち上げる
  2. 実行環境にAmazon S3バケットに保存されている関数のコードをダウンロードする
  3. 実行環境内でランタイムを初期化する(Node.jsおよびJavaのみ)
  4. ハンドラー外に記述されているコードを実行する(ライブラリのインポートなど)

INITフェーズが完了するとINVOKEフェーズに移行し、ハンドラーが実行されます。

ハンドラーの実行が完了した後もしばらくは実行環境が残り続けます。その間にLambda関数が新たに呼び出された場合、実行環境が再利用されハンドラーが実行されます。ちなみに、INVOKEフェーズから関数を実行する状態をウォームスタート、INITフェーズから実行する状態を(広義の)コールドスタートと呼びます。

コールド/ウォームスタートの解説

コールド/ウォームスタートの解説

ウォームスタートとコールドスタートを身近なところで例えるなら、自身のPCで、あるプログラムを実行する際にPCが起動済み(ウォームスタート)の状態なのか、起動するところ(コールドスタート)からなのかという違いがあります。

Lambda関数の呼び出しがしばらくないとSHUTDOWNフェーズに移行し実行環境が削除されます。

おわりに

さて、今回はAWS Lambdaの基礎編としてサービスの仕組みの説明をしました。AWS Lambda以外のマネージドサービスにも該当する話ですが、マネージドサービスは裏側が利用者からは分からない仕組みになっているので、性能改善にあたっては裏側の仕組み、今回であれば特にライフサイクルを理解しておくことが重要になってきます。次回以降は、このライフサイクルの観点からAWS Lambdaのパフォーマンスを実際にどのように改善していくのかを解説していきます。より実践的なノウハウを知りたい方はぜひ、今後のブログ掲載を楽しみにしていてください。また、当社では、AWSサービスの表面的な技術ノウハウに留まらず、サービスの裏側の仕組みまでを踏まえた上で、アプリケーションやアーキテクチャの改善提案をさせていただいています。AWS包括的技術支援サービスを提供しているのでAWS Lambdaのパフォーマンス改善に限らず、何かお困りごとがあればお気軽にお問い合わせください!

関連ページ

おすすめブログ

AWS Lambdaのパフォーマンス改善(1)
AWS Lambdaのパフォーマンス改善(1)
今回と次回では、実際にAWS Lambdaのパフォーマンスをどのように改善していくのかについて、具体的に解説していきます。
AWS Lambdaのパフォーマンス改善(2)
AWS Lambdaのパフォーマンス改善(2)
今回は、AWS LambdaのライフサイクルでINITフェーズの次にくるINVOKEフェーズのパフォーマンス改善方法を中心に説明していきます。