AWS Lambda

###1.Lambdaとは##
サーバーを実行せずに、"必要な時に"アプリケーションを実行する場合、Lambdaがあります。
Lambdaはサーバーのプロビジョニングや管理を行わずにコードを実行してくれます。
要するに、AWSに関するなにかしらのイベントによって処理を実行する環境で、イベント時に自分で作ったプログラムを実行してくれます。

一言でいうと、「難しいサーバー構築などなしに簡単にアプリのコードが動く！」





###2.特徴###

- 一番のポイントはEC2のような仮想サーバを立てる必要がないことです。（サーバレス）
- 処理件数が増えてくると、自動的に実行ユニットを増やして並列にスケールアウトしてくれます。そのため、CPUやメモリなの使用率に応じてオートスケール設定を調整するなどの作業は不要となります。
- 低コスト少ない労力でサービスを開発できますが、稼働時間やステートレス、リレーショナルデータベースとの相性があり、全てをEC2からLambdaに置き換えることは困難です。
- API Gateway をエンドポイント（ただのURLとして）とし、組み合わせて利用することで、簡単なWebサービスやAPIサービスを公開できます。時間帯によってアクセス数の変動が多いサイトや、特別な日だけアクセス数の急増するサイトに効果的。



###3.料金###
関数を実行するのにかかった時間だけ料金がかかります。
コードを実行していない時は課金されません。





###4.仕様###

- ディスク容量：最大 10 GB

https://aws.amazon.com/jp/about-aws/whats-new/2022/03/aws-lambda-configure-ephemeral-storage/

- メモリ：128Mbyteから 10 GBまで

https://aws.amazon.com/jp/blogs/aws/new-for-aws-lambda-functions-with-up-to-10-gb-of-memory-and-6-vcpus/

- タイムアウト：最長15分

https://aws.amazon.com/jp/blogs/news/aws-lambda-timeout-15min/

- デプロイのパッケージサイズとファイル記述子の最大数に制約を受けます。
- リクエストとレスポンスの本分のペイロードは6Mbyteを超過できません。
- イベントリクエストの本文も136Kbitに制限されます。
- 同時実行数はソフトリミットで、リクエストに応じて増やすことができます。
- コードがトリガーされる回数の基づいて、実行時間の1ミリ秒ごとに構築されます。





###5.ユースケース###

[AWS Lambda の使用方法の例]
(https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/use-cases.html)

以下のような場合は向いていない。

- 1回の処理時間が長いワークロード
- 24時間絶えずリクエストがあるWebサービス


###6.Demo###
[AWS Lambda とりあえず触ってみた](https://qiita.com/leomaro7/items/d8d8d4e10214115fc188)
[API Gateway + Lambda + DynamoDB](https://qiita.com/leomaro7/items/314a80b6d91f9e6b4060)
[サーバーレスアプリケーションでエラーに対処する (AWS Step Functions + AWS Lambda)](https://qiita.com/leomaro7/items/3cfbd549c14ec7e906a8)
[SQSのメッセージをトリガーにLambdaを起動する](https://qiita.com/leomaro7/items/28d646bb34f9a244c24f)
[ステージごとにAPIを作成することなく 各ステージごとにバックエンドポイントを振りわける](https://qiita.com/leomaro7/items/86ae586d278265720429)



###7.言語###
どの言語がおすすめか？

- アクセスがまばら　：　Node.js、Python（初動が早い）
- 常時アクセスないしは、大量のCPU　：　Java、Ruby、C#、Go (初回実行起動が遅い)

[カスタムランタイム](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/runtimes-custom.html)
　どのプログラミング言語でも実装できるようになりました。（C++ RUN など）
　※2020/09/08
　これまでLambdaのカスタムランタイムはAmazon Linux上で動作していましたが、追加の選択肢としてAmazon Linux2上でのカスタムランタイムが選択可能になりました。
　[AWS Lambda が Amazon Linux 2 のカスタムランタイムのサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2020/08/aws-lambda-supports-custom-runtimes-amazon-linux-2/)

###8.モデル###

- Pushモデル
 - S3／Cognito／SNSなどのAWSサービスとカスタムイベントが直接実行することにより起動するLambdaファンクション
 - サービスもしくはアプリが直接実行する
 - 順不同
 - 3回までリトライ
 - さらに細かくわけるとリソースによって処理結果をレスポンスとして受け取る同期呼び出しと処理の完了は待たない非同期呼び出しがサポートされている。

- Pullモデル
 - DynamoDBとKinesisなどのデータ処理はLambdaに対して直接的にイベント発行を行わないためLambdaがそれらへポーリングを行い自らイベントを取得
 -  上記のようなストリームベースとSQSのキューベースがある。
 - ストリームに入ってきた順に処理される
 -  イベントソースとして登録したストリームに対してLambdaが自動的にデータ取得などのファンクションを実行する
 -  イベントごとに複数レコードを取得可能
 -  データが期限切れになるまでリトライ


###9.パーミッション###

- Execution:LambdaファンクションがAWSリソースにどういったアクションを実施させるかを決定する → IAMみたいなもの
- Invocation:Lambdaファンクションをどのリソースが実行できるかを決定する → セキュリティグループみたいなもの


###10.2018年re:invent###

- Lambda Layer：Lambdaファンクション間で共通するコンポーネントをLambda Layerとして定義し参照できる（5つまで）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/fefc7f9e-afce-ca91-d5bf-2ddbf2c87e05.png)

- ロードバランサ―機能:ALBのバックエンドにLambdaを呼び出すことが可能になり、WEBアプリにLambdaファンクションを組込易くなった。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/f0ce7dce-c31d-6b81-618e-88e25f814f82.png)


###11.同時実行数とスロットリング、リトライ動作###
同一アカウントの同一リージョン内につき、1000に制限されています。（リージョンごとに適用され、AWSに申請することで引き上げることが可能です。）[AWS Lambda の制限
](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html)
Lambda関数の同時実行数が上限に達すると、それ以上の呼び出しはスロットリング（サービスが制限されること）され、実行されません。
スロットリングされたリクエストの処理方法は、イベントソースのタイプによって異なります。

- プッシュ型
 - 同期呼び出し型：

- プル型
 - ストリームベース：
 - キューベース：

||同期呼び出し型|非同期呼び出し型|ストリームベース|キューベース|
|---|---|---|---|---|
|スロットリング|Lambdaは429エラーを返却する。リトライするためには、呼び出し元でリトライ作業を行う必要がある。|非同期呼び出し型：Lambdaは最大６時間自動的に空けてリトライする。デットレターキューを設定することで、関数がスロットリングされた理由を調べることができる。|Lambdaはデータの有効期限が切れるまで、スロットリングされたデータの処理を試みる。処理に順序を保つため、データの有効期限が切れるか、処理が成功するまで同一のシャードから新しいレコードは読み込まれない。|Lambdaは正常に呼び出されるか、、キューの期限に達するまでスロットリングされたレコードの処理を試みる。|
|リトライ動作|Lambdaは429エラーを返却する。リトライするためには、呼び出し元でリトライ作業を行う必要がある。|Lambdaは2回まで自動的に間を空けてリトライする。デットレターキューを設定することで、関数がスロットリングされた理由を調べることができる。|Lambdaはデータの有効期限が切れるまで、スロットリングされたデータの処理を試みる。処理に順序を保つため、データの有効期限が切れるか、処理が成功するまで同一のシャードから新しいレコードは読み込まれない。|Lambdaはメッセージの処理に失敗すると、それをキューに返却する。そのメッセージは、可視性タイムアウト期間を過ぎると再度処理することができる。|


Lambda 関数が同時実行の制限を超えると、API Gateway によって 502 内部サーバーエラーが断続的に返されます。 
この場合、Lambda 関数の同時実行制限を増やし、ConcurrentExecutions メトリクスが制限に近づくと、Amazon CloudWatch から通知アラートが送信されるよう構成する必要があります。
[Investigating spikes in AWS Lambda function concurrency](https://aws.amazon.com/jp/blogs/compute/investigating-spikes-in-aws-lambda-function-concurrency/)

###12.外部ライブラリ###

- zip化し、Lambdaにアップロードする必要があります。
- Lambda関数のコードは必ずzipファイルのルートに配置する必要があります。


###13 AWS SAM###
Lambda関数をローカル環境で実行し、テストおよびデバックすることができます。


###14 VPCアクセス###

- Lambda関数からVPC内のEC2インスタンスやRDSインスタンスにアクセスするためには、VPCアクセス設定を行う必要があります。VPCアクセス設定では、Lambda関数からアクセスするVPCおよびサブネット、Lambda関数に割り当てるセキュリティグループ設定します。

- LambdaはENIを作成し、VPC内のリソースにアクセスできるようにします。このため、Lambda関数には、ENIの作成などの権限をもつポリシーを付与したIAMロールを割り当てておく必要があり、`AWSLambdaVPCAccessExecutionRole` というロールを利用すれば、簡単に作成することができます。

- なお、ENIの作成において昔は
　⇩このようにENIが作成されていたものが、
![lambda1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/6abc2955-5c70-c9b4-cf77-2010c2fd29a8.png)
　⇩このように改善さました。
![lambda2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/9e6a3251-e55c-339c-4539-479472f61310.png)
これは、余分なENIを消費したり、関数ごとにENIを作成してアタッチするまでの時間が改善されたということになります。
詳細は、[こちら](https://aws.amazon.com/jp/blogs/news/announcing-improved-vpc-networking-for-aws-lambda-functions/)の記事を参考にしてみてください。


###15.tmp###
Lambda関数を一時的に保存する際は、ローカルディレクトリー/tmpが使用されます。
Lambda関数は最大10GBとなり、その容量を保存する一時スペースとして利用されます。


###16.DLQ###
非同期呼び出し処理の試みが 3 回 とも失敗した場合、Lambda は Amazon SQS キューまたは Amazon SNS トピックにイベントを送信できます。
イベントを送信したいSNS トピックまたは SQSキューのARNを、Lambda 関数のDeadLetterConfig（DLQ）パラメータとして指定することで、DLQを設定できます。

検証したい場合は、下記のページが参考になりました。
[AWS LambdaがDead Letter Queueをサポートしました #reinvent AWS re:Invent 2016](https://dev.classmethod.jp/cloud/aws/lambda-supports-dead-letter-queue/)



###17.最適なメモリ###

- [AWS Compute Optimizer が AWS Lambda 関数の推奨事項の提供を開始](https://aws.amazon.com/jp/about-aws/whats-new/2020/12/aws-compute-optimizer-delivers-recommendations-aws-lambda-functions/)
- [[アップデート] AWS Compute Optimizer で Lambda 関数の最適なメモリサイズがレコメンド可能になりました！](https://dev.classmethod.jp/articles/aws-compute-optimizer-delivers-recommendations-aws-lambda-functions/)

AWS Compute Optimizer はリソースの利用状況から機械学習により最適なリソースサイズをレコメンデーションしてくれるサービスです。
Lambda 関数はメモリサイズに応じて CPU サイズが変動しますが、プロビジョニングが不十分な場合、エラー率が向上したりアプリケーションのレイテンシーが増加する可能性があります。
適切なメモリサイズをプロビジョニングすることで過剰リソースによる無駄なコストの削減、またはメモリのプロビジョニング不足を解消することでパフォーマンス最適化を図ることができます。
コンソールから AWS Compute Optimizer を有効化するだけで利用可能であり、無料です。なんとも嬉しいサービス。

###18.Lambda 関数 URL###

https://qiita.com/leomaro7/items/f2142431e10cd7cc470d