AWS Lambda
# Let’s Dive Deep into AWS Lambda
## Serverlessとは
- インフラのプロビジョニング不要、管理不要
- プロビジョニングが不要
- キャパシティプランニングが不要
- セキュリティパッチ適用といった保守作業が不要
- 自動でスケール
- 価値に対する支払い
- 事前に必要なコストが存在しない
- リクエスト数ならびに処理の実行時間に対しての課金
- コスト効率が良い
- 高可用かつ安全
- メンテナンス時間や定期的なダウンタイムが存在しない
- 高い可用性になるように設計されている
## AWS のComputeサービス
- EC2 (インスタンス・ハードウエア)
- Container Services(アプリケーション・OS)
- Lambda(関数・ランタイム)
基本的に下に行くほど自由度は低くなるが管理の手間が少なくなる
## Lambda の基本
- サポートされている言語、またはカスタムランタイムで用意した言語を利用
- それぞれが隔離されたコンテナ内で実行される
- 利用する言語の関数もしくはメソッドをハンドラーとして指定し、実行の際に呼び出す
- コードは依存関係も含めてビルド、パッケージングした上でアップロード
- ZIP形式
- アップロードしたものはS3に保存され、実行時以外は暗号化される
- S3のARNを指定することも可能
- Lambda 関数 - 基本設定
- 制限
- イベントソース
- 起動方法
- ポーリングベース
- ストリームベース
- それ以外
- 他のAWSリソースから呼び出される
- イベントソースによって呼び出しタイプが異なる
- リトライの動きも異なる
- 呼び出しのタイプも呼び出し元のAWSサービスによって異なる(同期、非同期)
- 呼び出しタイプ
- Tips
- タイプ
- 非同期呼び出し
- Invocation Type はEvent
- レスポンス内容はリクエストが正常に受け付けられたかどうかのみ
- 同期呼び出し
- InvocationtypeはRequestResponse
- 実効完了時にレスポンスが返ってくる
- 関数のリトライ
- ストリームベースでないイベントソース
- 同期呼び出し
- エラー発生時にはレスポンスヘッダにFunctionError が含まれる
- 非同期呼び出し
- 自動的に2回までリトライされ、その後イベントは破棄される
- リトライには遅延がある
- Dead Letter Queue を設定することで未処理のイベントをSQSキューまたはSNSトピックに移動させることができる
- ポーリングベース
- ストリームベース
- データの有効期限が切れるまでリトライを行う
- 失敗したレコードの有効期限が切れるか処理が成功するまで、そのシャードからの読み込みはブロックされ新しいレコードの読み込みは行われない
- ストリームベースではない
- メッセージは全てキューに帰り Visibility Timeout が過ぎればまた処理が行われ、その後成功すればキューが削除される
- 新しいメッセージの処理はブロックされない
- VPCアクセス
- VPC内のリソースへインターネットを経由せずにアクセス可能
- Lambda に対してVPCサブネットおよびセキュリティグループを指定
- 後から設定することも可能
- AZごとに1つ以上のサブネットを指定しておくことを推奨
- ENIを利用して実現
- 注意点
- IAMを用いたアクセス許可
- Lambda関数およびレイヤーようにリソースベースのアクセス許可ポリシーをサポート
- リソースごとに他のアカウントに使用許可を与えられる
- AWSサービスによる関数呼び出しを許可することも可能
- 同時実効数
- デフォルトでは1000
- 同時実効数を超えると429エラー
- アカウントで同時実効数に上限があるが、関数ごとに指定することも可能
- ポーリングベースかつストリームベースだとシャード数と等しい
- ポーリングベースでストリームベースではない
- 同時実効数までスケールアップするが、クセあり
- アカウントの同時実行数までスケールして、他のLambdaの起動を妨げる可能性あり
- 自動スケーリング
- 許可された値まで自動でスケーリング
- バースト後に1分ごとに500ずつ同時実効数がスケールしていく
- この値の上限緩和は不可
## Lambda 関数のライフサイクル
- ENIの作成(VPCを利用する場合は初期化に10~60秒かかる)
- コンテナの作成
- デプロイパッケージのロード
- デプロイパッケージの展開
- ランタイムの起動・初期化
- 関数/メソッドの実行(ここの実行時間に対して課金される)
- コンテナの破棄
## Lambda 関数の設定
- 同時実行数の管理(スロットリング)
- 環境変数
- 環境変数はKMSで暗号化される
- KMSを独自に利用することも可能
- バージョニング・エイリアス
- ある一時点のLambdaをバージョンとして管理できる
- エイリアスは特定バージョンに対するAlias
- 通常はAlias が別の関数バージョンを示すように更新されるとすぐに切り替わる
- Routing-config を利用することで2つのバージョン間でのリクエストトラフィックの割合を決められる
- Lambda Layers
- 特徴
- 注意点
- Layer は1つの関数で5つまで
- Layerの展開順
- 各言語に依存を解決する固有パスがある
- タグ付け
- デッドレターキュー(DLQ)
- 2回のリトライを経て失敗した場合SQS,SNSに飛ばすことができる
- カスタムランタイム
- Runtime bootstrap を含める必要がある
- Initialization Tasks
- 環境変数の読み取りなど
- 関数の初期化
- エラーハンドリング
- Processing tasks
- イベントの取得
- トレーシングヘッダの電波
- コンテキストオブジェクトの作成
- 関数ハンドラの呼び出し
- レスポンスのハンドリング
- エラーハンドリング
- クリーンアップ
- Runtime Interface
- カスタムランタイムのためのHTTP API
- 使い所
- Lambda の言語サポートのアップデートを待てない場合
- 古いバージョンを使い続けたい場合
- サポートされていない言語を利用したい場合
- モニタリング
- CloudWatch を用いたMetrices の監視
- 呼び出されれば最低1回実行することを保証しているので、呼び出されない場合、複数回呼び出されることはあり得る
- 冪等性の担保は自身でする必要がある
- メトリクスの意味を理解してみるとボトルネックが見えてくる
- AWS X-Ray を用いたトラブルシュート
- CloudTrail によるログ記録
- CloudWatch Events でスケジュール実行
- アプリケーションの管理
## 雑感
Lambda はなんでもできるし小さいところでAWSリソース同士をつなぐ役割を果たしたりできるので使い所を選ばない感じだ。ただ、リソースをどのくらい割り当てるかや、周辺リソースを勘案してチューニングする必要があるし、実行タイプ(同期、非同期、ストリームベース)などによって、大量に利用した時にパフォーマンスや料金が変わってくるので大切な要素だと思った。
今回はPart 1と Part2で 3と4に関してはベストプラクティスよりの話っぽい感じだった。ただYouTube でしか用意がないので、見られるタイミングで見たい。