チューニングの前にまずはLambdaファンクションの裏側で発生していることを理解する必要があります。
Lambdaファンクション実行時に裏側で起きていること
Durationに含まれないと実行時間の実績としてはユーザーが確認することができません。(逆に言えば料金の支払い対象にはならない。)
1.(ENIの作成)
これが起きるのはVPCを利用する場合のみです。この処理を行う場合はENIをアタッチするので10秒〜30秒くらいかかることになります。CloudWatchのDurationにはENIの作成にかかった時間は含まれません。
2.コンテナの作成
Lambdaファンクションを動かすためのコンテナが生成されます。CloudWatchのDurationに含まれない。
3.デプロイパッケージのロード
S3にアップロードしたzip形式のパッケージをダウンロードします。CloudWatchのDurationに含まれない。
4.デプロイパッケージの展開
S3にアップロードしたzip形式のパッケージを展開します。パッケージサイズが大きいとパッケージの展開に時間がかかるのでコードの最適化をして極力サイズを減らすようにした方が良いです。CloudWatchのDurationに含まれない。
5.ランタイム起動・初期化
各ランタイムの初期化処理(グローバル処理)。Javaであればコンストラクタ等の初期化処理が実行される。CloudWatchのDurationに含まれない。
6.関数/メソッドの実行
ハンドラに指定した関数やメソッドが実行される。CloudWatchのDurationに含まれるのはここだけ。
コールドスタート
1〜6を全て実行することをこのように呼びます。基本的に0にすることはできません。コールドスタートを許容できないのであればそのシステムにとってはLambdaの採用は最適ではありません。(年々早くなってはいるらしい。)
コールドスタートの問題点
1〜5までは全て同じ内容が実行されているので無駄になります。
コールドスタートが起きる条件
簡単に言えばコンテナがない場合に起きる。つまり安定的なリクエストがこない場合に発生する。
- そもそも一つもコンテナがない場合(一発目)
- 利用可能な数以上にリクエスト数が来た場合
- コード、設定を変更した場合
ウォームスタート
1〜5までの処理を再利用して効率化します。
Lambdaが遅くなる原因
プログラムの問題
Lambdaで記述したプログラム自体が遅い問題。AWS側での対処方法はない。言語仕様を確認する。
コンピューティングリソース不足
Lambdaのメモリ設定を見直す。(メモリ設定を見直すことでCPU能力もつられてよくなる。)、少ないメモリ数から徐々に増やしていって変わらなくなったメモリの値が最適値になる。
コールドスタート
コールドスタートは遅いです。
コールドスタートを早くするには?
コンピューティングリソース(メモリ設定)を増やす。
コンピューティングリソース(メモリ設定)が増えれば初期化処理自体も早くなる。一番簡単にできます。
ランタイムを変える。
- JVMは遅い。PythonやNode.js、Ruby等の非コンパイル言語の採用を検討する。
- ただし、一度温まってウォームスタートになった場合はコンパイル言語の方が早いのでアプリの特性を考えること。
パッケージサイズを小さくする。
サイズが大きいとZIPパッケージの展開に時間がかかる。
VPCは使用しない。
起動に時間がかかる。
VPC内のリソースと通信が必要であれば非同期にする。
RDBMSと通信が必要なのであればDynamoDB StreamsやAWS Lambdaを使用して非同期に通信するようにする。同期実行が必要な処理の場合はそもそもLambdaを使わないようにする。
初期化処理は遅延ロードを使う。
初期化処理をハンドラの外に書くとコールドスタートが遅くなるので遅延ロードを使うようにする。
アーキテクチャの問題
同期でinvokeせずにレスポンスが必要ない非同期処理にする。
レスポンスが必要な同期処理の場合は許可された実行数に達するとエラーになる。レスポンスが必要ない非同期処理ならリトライしてくれる。
Think Parallel(並列処理)
1つあたりのイベントを小さくして同時に並列で動かせるようなアーキテクチャ設計をします。
同時実行数
Lambdaの同時実行数は現在は1000まで行っているので、ほとんどの場合で引っかかることはないです。なるべく一つ一つの処理の実行時間を短くすることを心がけましょう。
ストリームベース(Kinesis、DynamoDB Streams)の場合
少しだけ考え方が異なります。ストリームの中にあるシャードの数だけ同時実行とみなされます。シャードを分割してシャードの数を増やすようにすることがパフォーマンスの改善につながります。
Lambdaの設計思想
RDBMSではなくDynamoDBと組み合わせる。
RDSとの接続はVPCコールドスタートの問題が付き纏うため。
この記事へのコメントはありません。