メニュー
AWS Lambda
開発者ガイド

AWS Lambda 関数を使用する際のベストプラクティス

AWS Lambda の使用時に推奨されるベストプラクティスを以下に示します。

関数コード

  • Lambda ハンドラ (エントリポイント) をコアロジックから分離します。これにより、関数の単体テストが実行しやすくなります。Node.js では、次のようになります。

    Copy
    exports.myHandler = function(event, context, callback) { var foo = event.foo; var bar = event.bar; var result = MyLambdaFunction (foo, bar); callback(null, result); } function MyLambdaFunction (foo, bar) { // MyLambdaFunction logic here }
  • コンテナの再利用を駆使して関数のパフォーマンスを向上させます。コードで取得する外部設定や依存関係が、最初の実行後はローカルで保存および参照されることを確認します。すべての呼び出しで変数/オブジェクトの再初期化を制限します。代わりに、静的初期化/コンストラクタ、グローバル/静的変数、およびシングルトンを使用します。前回の呼び出しで確立した接続を (HTTP、データベースなど) をキープアライブにして再利用します。

  • Environment Variables を使用してオペレーショナルパラメータを関数に渡します。たとえば、Amazon S3 に書き込む場合、書き込み先のバケットの名前はハードコーディングせずに、環境変数として設定します。

  • 関数のデプロイパッケージの依存関係を制御します。AWS Lambda 実行環境には、Node.js および Python ランタイムの AWS SDK などのライブラリがいくつか含まれています (詳細なリストについては、「Lambda 実行環境と利用できるライブラリ」を参照してください)。最新の機能やセキュリティ更新プログラムを有効にするために、Lambda ではこれらのライブラリを定期的に更新します。この更新に伴って、Lambda 関数の動作が微妙に変わる場合があります。関数で使用する依存関係を完全に制御するには、すべての依存関係をデプロイパッケージでパッケージングすることをお勧めします。

  • デプロイパッケージのサイズをランタイムに必要な最小限のサイズにします。これにより、呼び出しに先立ってデプロイパッケージをダウンロードして解凍する所要時間が短縮されます。Java または .NET Core で作成した関数の場合は、デプロイパッケージの一環として AWS SDK ライブラリ全体をアップロードしないようにします。代わりに、SDK のコンポーネントを必要に応じて選別するモジュール (DynamoDB モジュール、Amazon S3 SDK モジュール、Lambda コアライブラリ など) を使用します。

  • Java で記述されたデプロイパッケージを Lambda で解凍する所要時間を短縮します。そのために、依存する .jar ファイルを別個の /lib ディレクトリに収納します。これで関数のすべてのコードを多数の .class ファイルと一緒に単一の Jar に収納するよりも高速化されます。

  • 依存関係の複雑さを最小限に抑えます。フレームワークを単純化してコンテナの起動時のロードを高速化します。たとえば、Spring Framework などの複雑なフレームワークよりも、DaggerGuice などの単純な Java 依存関係インジェクション (IoC) フレームワークを使用します。

Function Configuration

  • Lambda 関数のパフォーマンステストは、最適なメモリサイズ設定を選択する上で欠かせない部分です。メモリサイズが増えると、関数で利用できる CPU も同様に増加します。関数のメモリ使用量は、呼び出しごとに決定され、AWS CloudWatch Logs で表示できます。次に示すように、呼び出しごとに REPORT: エントリが作成されます。

    Copy
    REPORT RequestId: 3604209a-e9a3-11e6-939a-754dd98c7be3 Duration: 12.34 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB

    Max Memory Used: フィールドを分析することで、関数のメモリが不足しているか、関数のメモリサイズをオーバープロビジョニングしているかを判断できます。

  • Lambda 関数のロードテストにより、最適なタイムアウト値を決定します。関数の実行時間を分析し、依存関係サービスの問題に伴って関数の同時実行が必要以上に増えるような状況をより的確に判定します。これは、Lambda のスケーリングを処理しない可能性があるリソースに対して Lambda 関数からネットワークの呼び出しを行うときに特に重要です。

  • IAM ポリシーの設定時に最も制限的なアクセス許可を使用します。Lambda 関数に必要なリソースとオペレーションを把握し、実行ロールをこれらのアクセス許可に制限します。詳細については、「AWS Lambda に対する認証とアクセスコントロール」を参照してください。

  • AWS Lambda の制限 に精通します。ランタイムのリソース制限を決定する際に、ペイロードサイズ、ファイル記述子、および /tmp スペースが見過ごされがちです。

  • 使用しなくなった Lambda 関数を削除します。削除することで、未使用の関数がデプロイパッケージサイズの制限対象として不必要にカウントされなくなります。

アラームとメトリクス

  • AWS Lambda のメトリクス および CloudWatch アラームを使用し、Lambda 関数コード内からはメトリクスを作成または更新しないようにします。Lambda 関数の状態を追跡する方法としてより効率的であり、開発プロセスの早期に問題を把握できます。たとえば、Lambda 関数の推定される実行所要時間に基づいてアラームを設定し、関数コードに起因するボトルネックやレイテンシーに対処できます。

  • ログ記録のライブラリと AWS Lambda メトリクスおよびディメンションを活用して、アプリケーションエラー (ERR、ERROR、WARNING など) を見つけます。

ストリームイベントの呼び出し

  • バッチおよびレコードの各種サイズのテストにより、関数がタスクを完了できるスピードに合わせて各イベントソースのポーリング間隔を調整します。BatchSize は、各呼び出しで関数に送信できるレコードの最大数を制御します。通常、バッチサイズが大きいほど、大きなレコードセット全体での呼び出しのオーバーヘッドをより効率的に吸収し、スループットを増大できます。

    注記

    処理対象のレコード数が十分でない場合は、待機する代わりに、少数のレコードを処理するストリーム処理関数を呼び出します。

  • シャードを追加して Kinesis ストリーム処理のスループットを向上させます。Kinesis ストリームは 1 つ以上のシャードで構成されます。Lambda は、最大で 1 つの同時呼び出しを使用して各シャードをポーリングします。たとえば、ストリームに 100 個のアクティブなシャードがある場合は、最大で 100 個の Lambda 関数呼び出しが同時に実行されます。シャードの数を増やすと、直接的な結果として、Lambda 関数の同時呼び出しの最大数が増えます。また、Kinesis ストリーム処理のスループットが増える場合があります。Kinesis ストリームのシャード数を増やす場合は、データの適切なパーティションキー (パーティションキーを参照) を選択していることを確認し、関連レコードが同じシャードに割り当てられ、データが適切に配分されるようにします。

  • Amazon CloudWatch を IteratorAge で使用し、Kinesis ストリームが処理されているかどうかを判断します。たとえば、CloudWatch アラームを最大値の 300000 (30 秒) に設定します。

非同期呼び出し

Lambda VPC

  • 次の図は、VPC (Virtual Private Cloud) を使用するかどうかを判断するデシジョンツリーです。

  • 必要でない限り、Lambda 関数を VPC に配置しません。プライベートな Amazon Relational Database インスタンスなど、パブリックに公開できないリソースにアクセスする以外に、この関数の利点はありません。Amazon Elasticsearch Service などのサービスは IAM のアクセスポリシーで保護できるため、エンドポイントをパブリックに公開しても安全であり、エンドポイントを保護するために VPC で関数を実行する必要はありません。

  • Lambda は、VPC で Elastic Network Interface (ENI) を作成して内部リソースにアクセスします。同時実行の増加をリクエストする前に、ENI キャパシティーが十分であること (その数式は「Amazon VPC 内のリソースにアクセスできるように Lambda 関数を構成する」にあります) および IP アドレスのスペースが十分であることを確認します。ENI キャパシティーが十分でない場合は、増加をリクエストする必要があります。IP アドレスのスペースが十分でない場合は、必要に応じて、より大きなサブネットを作成します。

  • Lambda 専用サブネットを VPC に作成します。

    • これにより、他のプライベート/パブリックサブネットを変更しないで、より簡単にカスタムルートテーブルを NAT ゲートウェイトラフィックに適用できます。詳細については、「Amazon VPC 内のリソースにアクセスできるように Lambda 関数を構成する」を参照してください。

    • これにより、他のリソースと共有せずに専用のアドレス空間を Lambda に割り当てることができます。