

# AWS Lambda 関数を使用するためのベストプラクティス
<a name="best-practices"></a>

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

**Topics**
+ [関数コード](#function-code)
+ [Function Configuration](#function-configuration)
+ [関数のスケーラビリティ](#function-scalability)
+ [メトリクスおよびアラーム](#alarming-metrics)
+ [ストリームの使用](#stream-events)
+ [セキュリティのベストプラクティス](#security-best-practices)

## 関数コード
<a name="function-code"></a>

**実行環境の再利用を活用して関数のパフォーマンスを向上させます。**関数ハンドラー外で SDK クライアントとデータベース接続を初期化し、静的なアセットを `/tmp` ディレクトリにローカルにキャッシュします。関数の同じインスタンスで処理された後続の呼び出しは、これらのリソースを再利用できます。これにより、関数の実行時間が短縮され、コストが節約されます。

呼び出し間でデータが漏れるのを防ぐため、実行環境を使用してセキュリティ上の懸念があるユーザーデータ、イベント、またはその他の情報を保存しないでください。関数がハンドラー内のメモリに保存できない変更可能な状態に依存している場合は、ユーザーごとに個別の関数または個別のバージョンの関数を作成することを検討してください。

**keep-alive ディレクティブを使用して永続的な接続を維持します。**Lambda は、時間の経過とともにアイドル状態の接続を消去します。関数を呼び出すときにアイドル状態の接続を再利用しようとすると、接続エラーが発生します。永続的な接続を維持するには、ランタイムに関連付けられている keep-alive ディレクティブを使用します。例については、「[Node.js で Keep-alive を使用して接続を再利用する](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)」を参照してください。

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

Lambda 関数では、**再帰呼び出しを使用しないでください**。関数が自身を呼び出すこともあれば、新たに開始されたプロセスで関数が再度呼び出される可能性もあります。これを行うと意図しないボリュームで関数が呼び出され、料金が急増する可能性があります。意図しない呼び出しがいくつも見つかった場合は、すぐに関数の予約済同時実行数を `0` に設定して、コードを更新している間のすべての関数の呼び出しをスロットリングします。

Lambda 関数コードで**文書化されていない非公開の API を使用しないでください**。AWS Lambda マネージドランタイムでは、Lambda が Lambda の内部 API にセキュリティと機能面の更新を定期的に適用します。これらの内部 API 更新には後方互換性がないことがあり、関数にこれらの非公開 API に対する依存関係がある場合、呼び出しの失敗などの意図しない結果につながります。公開されている API のリストについては、「[API リファレンス](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)」を参照してください。

**冪等性コードを記述します。**関数の記述に冪等性コードを使用すると、重複するイベントが同じ方法で処理されるようになります。コードでは、イベントを適切に検証し、重複するイベントを適切に処理する必要があります。詳細については、「[Lambda 関数を冪等にするにはどうすればよいですか?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/)」を参照してください。

**注記**  
Powertools for AWS Lambda を使用して、関数をべき等にすることができます。詳細については、以下を参照してください。  
[Python - べき等性ユーティリティ](https://docs.aws.amazon.com/powertools/python/latest/utilities/idempotency/)
[TypeScript - べき等性ユーティリティ](https://docs.aws.amazon.com/powertools/typescript/latest/features/idempotency/)
[Java - べき等性ユーティリティ](https://docs.aws.amazon.com/powertools/java/latest/utilities/idempotency/)
[.NET - べき等性ユーティリティ](https://docs.aws.amazon.com/powertools/dotnet/utilities/idempotency/)

言語固有のコードのベストプラクティスについては、以下のセクションを参照してください。
+ [Node.js Lambda 関数のコードのベストプラクティス](nodejs-handler.md#nodejs-best-practices)
+ [TypeScript Lambda 関数のコードのベストプラクティス](typescript-handler.md#typescript-best-practices)
+ [Python Lambda 関数のベストプラクティスに従ってください。](python-handler.md#python-handler-best-practices)
+ [Ruby Lambda 関数のベストプラクティスに従ってください。](ruby-handler.md#ruby-best-practices)
+ [Java Lambda 関数のコードのベストプラクティス](java-handler.md#java-best-practices)
+ [Lambda 関数のコードのベストプラクティス](golang-handler.md#go-best-practices)
+ [C\$1 Lambda 関数のコードのベストプラクティス](csharp-handler.md#csharp-best-practices)
+ [Rust Lambda 関数のコードのベストプラクティス](rust-handler.md#rust-best-practices)

## Function Configuration
<a name="function-configuration"></a>

**Lambda 関数のパフォーマンステスト**は、最適なメモリサイズ設定を選択する上で欠かせない部分です。メモリサイズが増えると、関数で利用できる CPU も同様に増加します。関数のメモリ使用量は呼び出しごとに決定され、[Amazon CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatchLogs.html) で表示できます。次に示すように、呼び出しごとに `REPORT:` エントリが作成されます。

```
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:` フィールドを分析することで、関数のメモリが不足しているか、関数のメモリサイズをオーバープロビジョニングしているかを判断できます。

関数のために**適切なメモリの構成を見つけるには**、オープンソースの AWS Lambda Power Tuning プロジェクトを使用することを推奨しています。詳細については、GitHub の [AWS Lambda Power Tuning](https://github.com/alexcasalboni/aws-lambda-power-tuning) を参照してください。

関数のパフォーマンスを最適化するためには、Advanced Vector Extensions 2 (AVX2) が利用可能なライブラリのデプロイも推奨されます。これにより、機械学習による推定、メディア処理、ハイパフォーマンスコンピューティング (HPC)、科学シミュレーション、財務モデリングなど、負荷が大きくなりがちなワークロードを処理できるようになります。詳細については、[AVX2 を使用した高速な AWS Lambda 関数の作成](https://aws.amazon.com/blogs/compute/creating-faster-aws-lambda-functions-with-avx2/)を参照してください。

**Lambda 関数のロードテストにより**、最適なタイムアウト値を決定します。関数の実行時間を分析し、依存関係サービスの問題に伴って関数の同時実行が必要以上に増えるような状況をより的確に判定します。これは、Lambda のスケーリングを処理しない可能性があるリソースに対して Lambda 関数からネットワークの呼び出しを行うときに特に重要です。アプリケーションの負荷テストの詳細については、「[AWS の分散負荷テスト](https://aws.amazon.com/solutions/implementations/distributed-load-testing-on-aws/)」 を参照してください。

**IAM ポリシーの設定時に最も制限的なアクセス許可を使用します。**Lambda 関数に必要なリソースとオペレーションを把握し、実行ロールをこれらのアクセス許可に制限します。詳細については、「[AWS Lambda アクセス許可の管理](lambda-permissions.md)」を参照してください。

** について理解を深めます。。[Lambda クォータLambda クォータ](gettingstarted-limits.md)**ランタイムのリソース制限を決定する際に、ペイロードサイズ、ファイル記述子、および /tmp スペースが見過ごされがちです。

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

イベントソースとして **Amazon Simple Queue Service** を使用している場合、関数の予想呼び出し時間の値が、キューの[可視性タイムアウト](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html)の値を超過していないことを確認してください。これは、[CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html) および [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html) の両方に適用されます。
+ **CreateFunction** の場合、AWS Lambda における関数の作成プロセスは失敗します。
+ **UpdateFunctionConfiguration** の場合、関数の呼び出しが重複する可能性があります。

## 関数のスケーラビリティ
<a name="function-scalability"></a>

**アップストリームおよびダウンストリームでのスループットの制約について理解を深めます。**Lambda 関数は負荷に応じてシームレスにスケールしますが、アップストリームとダウンストリームの依存関係においてスループット能力は同じではない場合があります。関数がスケーリングできる高さを制限する必要がある場合、関数に [予約された同時実行数を設定](configuration-concurrency.md) できます。

**スロットリング耐性を組み込みます。**Lambda のスケーリングレートを超えるトラフィックが原因で同期関数にスロットリングが発生した場合、次の戦略を使用してスロットリング耐性を改善できます。
+ **「[ジッターを伴うタイムアウト、再試行、バックオフ](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/)」を使用します**。これらの戦略を実装すると、呼び出しの再試行がスムーズになり、Lambda が数秒以内にスケールアップしてエンドユーザーのスロットリングを最小限に抑えることができます。
+ **[プロビジョニングされた同時実行数](provisioned-concurrency.md) を使用します**。プロビジョニングされた同時実行は、Lambda が関数に配分する事前初期化済みの実行環境の数です。Lambda は、利用可能なときにプロビジョニングされた同時実行を使用し、受信リクエストを処理します。Lambda は、必要に応じてプロビジョニングされた同時実行設定を超えて、関数をスケーリングすることもできます。プロビジョニングされた同時実行を設定すると、AWS アカウントに追加料金が請求されます。

## メトリクスおよびアラーム
<a name="alarming-metrics"></a>

**[Lambda での CloudWatch メトリクスの使用](monitoring-metrics.md) および [CloudWatch アラーム](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)を使用することで**、Lambda 関数コード内からメトリクスを作成または更新しないようにします。Lambda 関数のヘルスを追跡する方法としてより効率的であり、デプロイプロセスの早期で問題を把握できます。たとえば、Lambda 関数の推定される呼び出し所要時間に基づいてアラームを設定し、関数コードに起因するボトルネックやレイテンシーに対処できます。

**Embedded Metric Format (EMF) を使用して、カスタムメトリクスを非同期的に出力します。**CloudWatch に同期 API コールを実行する代わりに、EMF を使用して関数のログを介してメトリクスを出力します。このアプローチにより、レイテンシーが短縮され、パフォーマンスが向上します。Powertools for AWS Lambda のメトリクスユーティリティは、EMF フォーマットを自動的に処理します。詳細については、Powertools for AWS Lambda ドキュメントの [Python](https://docs.aws.amazon.com/powertools/python/latest/core/metrics/)、[TypeScript](https://docs.aws.amazon.com/powertools/typescript/latest/features/metrics/)、[Java](https://docs.aws.amazon.com/powertools/java/latest/core/metrics/)、または [.NET](https://docs.aws.amazon.com/powertools/dotnet/core/metrics/) Metrics ユーティリティを参照してください。EMF を使用してメトリクス形式のログを生成する方法については、「Amazon CloudWatch ユーザーガイド」の「[埋め込みメトリクス形式を使用したログの発行](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Generation.html)」を参照してください。

**オブザーバビリティを向上させるには、構造化された JSON ログ記録を使用します。**構造化ログ記録を使用すると、関数のログの検索、フィルタリング、分析が容易になります。Powertools for AWS Lambda の Logger ユーティリティを使用して、JSON でログを自動的にフォーマットすることを検討してください。詳細については、Powertools for AWS Lambda ドキュメントの [Python](https://docs.aws.amazon.com/powertools/python/latest/core/logger/)、[TypeScript](https://docs.aws.amazon.com/powertools/typescript/latest/features/logger/)、[Java](https://docs.aws.amazon.com/powertools/java/latest/core/logging/)、または [.NET](https://docs.aws.amazon.com/powertools/dotnet/core/logging/) Logger ユーティリティを参照してください。

**ログ記録のライブラリや[AWS Lambda メトリクスとディメンションを活用](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/lam-metricscollected.html)**して、アプリケーションエラー (ERR、ERROR、WARNING など) を補足します。

**[AWS コスト異常の検出](https://docs.aws.amazon.com/cost-management/latest/userguide/manage-ad.html)を使用**して、アカウントの異常なアクティビティを検出します。コスト異常の検出は、機械学習を使用し、コストと使用量を継続的にモニタリングしながら誤検出アラートを最小限に抑えます。コスト異常の検出は、AWS Cost Explorer のデータを使用しますが、データには最大 24 時間の遅延があります。その結果、使用を開始してから異常を検出するまでに最大 24 時間かかる場合があります。コスト異常の検出を開始するには、まず [Cost Explorer にサインアップ](https://docs.aws.amazon.com/cost-management/latest/userguide/ce-enable.html)する必要があります。次に、[コスト異常の検出をアクセス](https://docs.aws.amazon.com/cost-management/latest/userguide/settingup-ad.html#access-ad)します。

## ストリームの使用
<a name="stream-events"></a>

**バッチおよびレコードの各種サイズのテスト**により、関数がタスクを完了できるスピードに合わせて各イベントソースのポーリング間隔を調整します。[CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) BatchSize パラメータは、各呼び出しで関数に送信できるレコードの最大数を制御します。通常、バッチサイズが大きいほど、大きなレコードセット全体での呼び出しのオーバーヘッドをより効率的に吸収し、スループットを増大できます。

デフォルトで、Lambda はレコードが使用可能になると同時に関数を呼び出します。Lambda がイベントソースから読み取るバッチにレコードが 1 つしかない場合、Lambda は関数に 1 つのレコードしか送信しません。少数のレコードで関数を呼び出さないようにするには、*バッチ処理ウィンドウ*を設定することで、最大 5 分間レコードをバッファリングするようにイベントソースに指示できます。関数を呼び出す前に、Lambda は、完全なバッチを収集する、バッチ処理ウィンドウの期限が切れる、またはバッチが 6 MB のペイロード制限に到達するまでイベントソースからのレコードの読み取りを継続します。詳細については、「[バッチ処理動作](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching)」を参照してください。

**警告**  
Lambda イベントソースマッピングは各イベントを少なくとも 1 回処理し、レコードの重複処理が発生する可能性があります。重複するイベントに関連する潜在的な問題を避けるため、関数コードを冪等にすることを強くお勧めします。詳細については、AWS ナレッジセンターの「[Lambda 関数を冪等にするにはどうすればよいですか?](https://repost.aws/knowledge-center/lambda-function-idempotent)」を参照してください。

**ストリーム処理の部分的なバッチレスポンスを有効にします。**Kinesis や DynamoDB Streams などのストリームからのレコードのバッチを処理する場合、部分的なバッチレスポンスを有効にして、Lambda がバッチ全体ではなく失敗したレコードのみを再試行できるようにします。これにより、処理効率が向上し、不要な再処理が軽減されます。オプションで Powertools for AWS Lambda からのバッチユーティリティを使用して、バッチ処理パターンを簡素化できます。

**注記**  
バッチ処理には、Powertools for AWS Lambda を使用できます。詳細については、以下を参照してください。  
[Python - Batch 処理](https://docs.aws.amazon.com/powertools/python/latest/utilities/batch/)
[TypeScript - Batch 処理](https://docs.aws.amazon.com/powertools/typescript/latest/features/batch/)
[Java - Batch 処理](https://docs.aws.amazon.com/powertools/java/latest/utilities/batch/)
[.NET - Batch 処理](https://docs.aws.amazon.com/powertools/dotnet/utilities/batch-processing/)

**シャードを追加して Kinesis ストリーム処理のスループットを増加させます。**Kinesis ストリームは 1 つ以上のシャードで構成されます。Lambda が Kinesis からデータを読み取る速度は、シャードの数に応じて線形的にスケールします。シャードの数を増やすと、直接的な結果として、Lambda 関数の同時呼び出しの最大数が増えます。また、Kinesis ストリーム処理のスループットが増える場合があります。シャードと関数呼び出しとの関係の詳細については、「[ポーリングストリームとバッチストリーム](with-kinesis.md#kinesis-polling-and-batching)」を参照してください。Kinesis ストリームのシャード数を増やす場合は、データの適切なパーティションキー (「[パーティションキー](https://docs.aws.amazon.com/streams/latest/dev/key-concepts.html#partition-key)」を参照) を選択していることを確認し、関連レコードが同じシャードに割り当てられ、データが適切に配分されるようにします。

**[Amazon CloudWatch](https://docs.aws.amazon.com/streams/latest/dev/monitoring-with-cloudwatch.html) を IteratorAge で使用し**、Kinesis ストリームが処理されているかどうかを判断します。たとえば、CloudWatch アラームを最大値の 30,000 (30 秒) に設定します。

## セキュリティのベストプラクティス
<a name="security-best-practices"></a>

**AWS Security Hub CSPM を使用して、セキュリティのベストプラクティスに関連する AWS Lambda の使用状況をモニタリングします。**Security Hub CSPM によってセキュリティコントロールが使用されてリソース設定およびセキュリティ標準が評価され、さまざまなコンプライアンスフレームワークに準拠できるようにサポートします。Security Hub CSPM を使用して Lambda リソースを評価する方法の詳細については、「AWS Security Hub CSPM ユーザーガイド」の「[AWS Lambda 制御](https://docs.aws.amazon.com/securityhub/latest/userguide/lambda-controls.html)」を参照してください。

**Amazon GuardDuty Lambda Protection を使用し、Lambda ネットワークのアクティビティログを監視します。**GuardDuty Lambda Protection は、AWS アカウント で Lambda 関数が呼び出されたときの潜在的なセキュリティ脅威を特定するために役立ちます。例えば、1 つの関数が暗号通貨関連のアクティビティに関連付けられている IP アドレスをクエリしたとします。GuardDuty は、Lambda 関数が呼び出されたときに生成されるネットワークアクティビティのログを監視します。詳細については、「*Amazon GuardDuty ユーザーガイド*」の「[Lambda 保護](https://docs.aws.amazon.com/guardduty/latest/ug/lambda-protection.html)」を参照してください。