概要
AWS Lambda の勉強を始めようと「AWSによるサーバーレスアーキテクチャ」を購入
少し読んでみると非常に良い本なので書籍紹介と自身のLambda備忘録のために投稿
Lambdaについての概要、使い方、制限、注意事項などまとめていく予定
紹介書籍
サーバーレスアーキテクチャの原則
- オンデマンドでコードを実行するために、(サーバーではなく)コンピューティングサービスを使う
- 目的が1つでステートレスな関数を書く
- プッシュベースのイベント駆動パイプラインを設計する
- より厚く、より強力なフロントエンドを作る
- サードパーティサービスを活用する
サーバーレスの長所と短所
長所
- サーバー管理不用
- 低コスト
- 市場投入までの時間短縮
- 実装がシンプル、コード量減る可能性がある
- ☆マルチスレッドを考慮する必要がない
- スケーラブルで柔軟、並列処理が得意
短所
- レイテンシーに厳しい制約のあるAPには向かない
- ベンダーロックイン
- パブリッククラウドが提供できる水準よりも高いパフォーマンス、信頼性が求めらえるミッションクリティカルサービスに向かない
- サービス分散化による、リモート呼び出し、ネットワーク越しのエラー処理、レイテンシーの増加
- OSのカスタマイズやその下のインスタンスの調整はできない
- Lambda特有の処理(複数回実行される等)が発生することがある
Lambda呼び出し方法
- イベント駆動型(非同期型)
- プッシュモデル
- プルモデル
- 要求/応答型(同期型)
〇Lambda関数実行までの流れ(※1)
- ENIの作成
- コンテナの作成
- デプロイパッケージのロード
- デプロイパッケージの展開
- ランタイム起動・初期化
- 関数/メソッドの実行
- 1.ENIの作成はVPCを利用する場合だけ
- すべてを実行するのがコールドスタート/6.だけ実行するのがウォームスタート
Lambda関数の状態
- コールド状態:関数のコードがロードされておらず、初期化、セットアップコードがこれから実行される状態
- ウォーム状態:一度以上関数が実行されており関数のコードがロードされている状態
(処理起動時間がかかる)コールド状態を減らすための施策
- 関数をウォーム状態に保つためにスケジュールイベントを使って定期的に実行するようにする
- 初期化、セットアップコードをイベントハンドラの外に出す。コンテナがウォーム状態なら、そのコードは実行されない
- Lambda関数に割り当てられるメモリの容量を増やす。CPUのシェアは、関数に割り当てられたメモリ容量に応じて決まる
- コードのサイズをできる限り小さくする。不要なモジュールを減らし、インポートのためのrequires()の呼び出しも減らす。インクルードおよび初期化するモジュールを減らせば、起動時のパフォーマンスを上げることができる
- 別の言語も検討してみる。(将来変わるかもしれないが)コールドスタートが最も長いのはJava
- 「新機能 – Lambda 関数のプロビジョニングされた同時実行性」を使用してみる
Lambdaの制限
- 一時ディスク:512MB
- ファイルディスクリプタの数:1024
- プロセスとスレッドの数:1024
- リクエストあたりの処理時間:300秒
- 呼び出し時のリクエスト本体のペイロードサイズ(要求/応答型):6MB
- 呼び出し時のリクエスト本体のペイロードサイズ(イベント駆動型):128KB
- 呼び出し時のレスポンス本体のペイロードサイズ(要求/応答型):6MB
AWS ドキュメント
AWS Lambda の制限
SDKによるLambda関数直接呼び出しの注意事項
- ユーザーがSDKの一部をダウンロードしなければならない
- Lambda関数の呼び出し方法を変える場合は、クライアント/Lambda関数両方に修正が入る可能性がある
- 悪意のあるユーザーがクライアントプログラムを変更することで、Lambda関数を不正に呼び出すことができてしまう
- HTTP(s)を使った統一的なRESTインターフェイスにならない
Amazon API Gatewayとの連携
Lambdaプロキシ統合について
- Lambda統合プロキシ有効:すべてのリクエスト(クエリ文字列、ヘッダー、ステージ変数、パス変数、リクエストコンテキスト、リクエスト本体)をJSONに変換し、イベントオブジェクトとしてLambdaに渡す
- Lambda統合プロキシ無効:統合Request(Response)セクションでマッピングテンプレートを作って、HTTPリクエストをどのようにJSONにマッピングするか定義する必要がある
- リクエスト本体のペイロードは無効の状態でもマッピングされる
- 例えば、HTTPヘッダの Authorization をLambdaのeventオブジェクト変数(authTokenという名前とする)にマッピングする場合は以下のように定義する
{
"authToken" : "$input.params('Authorization')"
}
※$inputは、API Gateway上の変数。詳細は以下のリファレンスを参照
API Gateway のマッピングテンプレートリファレンス
- ☆統合プロキシを使って、API Gateway(XML)をLambda(JSON)にマッピング変換することはできない
- 統合プロキシを使ってXMLをそのままRAWデータとしてLambdaに送ってLambdaで解析することは可能
- その場合、以下のようにマッピング定義をする
{
"body" : $input.json('$')
}
参考URL
Using API Gateway to pass non-JSON data (e.g. XML) to a Lambda
- Amazon API Gateway での統合タイムアウトのカスタマイズ
- タイムアウト値は 50 ミリ秒〜29 秒の間で設定可能
- https://aws.amazon.com/jp/about-aws/whats-new/2017/11/customize-integration-timeouts-in-amazon-api-gateway/
LambdaとRDSのコネクション数問題について
- 負荷に合わせて異なるサーバーリソースで拡張していくサーバーレスの特徴から長年?制限とされていたLambdaとRDSのコネクション数増加問題についてAWS側で新しい機能がリリースされた(Amazon RDS Proxy)
- AWS LambdaでAmazon RDS Proxyを使用する
補足
☆印は自身の見解として追加
〇印は他の資料からの参照
参照
※1:全部教えます!サーバレスアプリのアンチパターンとチューニング