こんばんは。kitonです。
DVAの勉強中にLambdaのベストプラクティスについての問いが耳が痛くなるほど出てたので、勉強の合間でまとめました。
ベストプラクティス
やったほうが良いこと
Lambdaハンドラーをコアロジックから分離
- 関数の単体テストが実行しやすくなる。
例)
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
}
実行環境を再利用
- ハンドラー外でSDKクライアントとデータベース接続を初期化し、静的情報を/tmpディレクトリにキャッシュすることで、関数の実行時間が短縮し、コストも節約する。
※注意:ユーザーデータ、イベント、DB情報などは、セキュリティ上保存してはダメ。
keep-aliveで永続的な接続を維持
- 時間経過とともにアイドル状態の接続を消去する。
- ランタイムに関連付けられているkeep-aliveディレクティブを使用する。
環境変数を使用
- ハードコーディングせず、環境変数として設定する。
関数のデプロイパッケージ内で依存関係を制御
- 実行環境では、多くのライブラリが提供されているが、パッチが定期的に行われることで、Lambdaの動作が変わる可能性がある。なので、全ての依存関係をデプロイパッケージでパッケージングする。
デプロイパッケージを最小限のサイズにする
- ダウンロードして解凍する時間が短縮される。
- SDKライブラリ全体をロードしないようにする。
- Javaの場合は.jarファイルを/libディレクトリに入れておく。.classファイルと一緒に単一のjarに格納するよりも高速化される。
冪等性コードを記述
下記問題を減らすことに役立つ。
- 不要な API 呼び出し
- コードの処理時間
- データの不整合
- スロットル
- レイテンシー
使用しなくなったLambda関数を削除する
- デプロイパッケージサイズの制限対象としてカウントされるのを防ぐため。
してはいけないこと
複雑な依存関係のフレームワークを使用しない
- 単純なJava依存関係インジェクションフレームワークを使用する。
(spring bootよりかはDagger,Guiceを使用する)
再帰的なコードは絶対に使用しない
- 高額請求間違いなし。やっちまった場合は、予約済同時実行数を0に設定。
コード内で非公開のAPIを使用しない
- 下記ドキュメントを確認して使用すること
Lambda関数コード内からメトリクスを作成、更新しないようにする
- Lambda関数のメトリクス、CloudWatchアラームを使用すること。
CostExplorerを使用する
- コストの異常を検出するため。
確認した方が良いこと
パフォーマンステスト
- メモリサイズ選定は慎重に。。(CPUも影響する)
Max Memory Usedを分析する。
REPORT RequestId: 3604209a-e9a3-11e6-939a-754dd98c7be3 Duration: 12.34 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB
- タイムアウト値の検討
- 実行時間を分析し、関数の同時実行が必要以上に増えないようにする。
- Lambda関数からネットワークの呼び出しなどでは重要。
- SQSを使用している場合、キューの可視性タイムアウトの値を超過しないこと。
Lambdaのクォータ
セキュリティ
-
IAMポリシーに適切なアクセス許可を行う。
最小限の原則。フルアクセスはNG。 -
AWS Security Hubを使用する
Lambdaの設定がコンプライアンスフレームワークに準拠できているか確認するため。
参考サイト