はじめに
個人請負でとあるサイトをサーバーレスで構築しています。
よくあるAmazon API Gatewayでリクエストを受けてAWS Lambdaで処理を行って結果を返却する簡単な構造なのですが・・・Lambdaからのリクエストが初回だけとにかく遅い!
原因は関数実行前の準備に時間がかかるからです。
Lambdaというサービスの内部では、初回実行時に実行する関数のパッケージのロードや展開、ランタイムの起動など色々な 「実行前準備」 をやってくれています。
しかし、一定時間関数が呼び出されないと 「実行前準備」 がアンロードされてしまうのです。そのため実行頻度の低いLambdaの場合は毎回遅い初回実行になってしまいます。
今回は色々と試してみてなんとか解決した方法を載せておきます。
前提
この方法が有効なケースは以下の場合です。
- Lambdaの実行頻度が低い。※30分に1度程度しか実行されないなど
デプロイパッケージのサイズをランタイムに必要な最小限のサイズにしていることやJavaよりPythonを選択している等も速度に影響してきますが今回は実行頻度が低い場合のみを対象としています。
解決した方法
なんと 「Lambdaを定期的に実行する」 だけです。
邪道のような気もしますがこれが一番効果がありました。
一定時間関数が呼び出されないと 「実行前準備」 がアンロードされてしまうのでアンロードされる前に再度実行だけしておく。そりゃ効果ありますよね。
今回は 5分毎 に実行するようにLambdaのトリガーを追加しました。
始めは1分毎で設定してみたのですが5分でも大丈夫そうなので5分毎に変更しています。
AWS Lambdaは関数に対するリクエストの数とコードの実行時間に基づいて課金されるので「コストあがっちゃうよ!」ってお考えの方もいらっしゃるかもしれませんが安心してください。1日288回プラスになるだけです。誤差です。
では早速設定してみます。
関数を選択した状態で 「トリガーを追加」 をクリックします。

トリガーの種類を選択できるので、 「EventBridge(CloudWatch Events)」 を選択します。

「新規ルールの作成」 を選択し、ルール名を入力します。
今回は「scheduled-execution」としました。

次にルールタイプを選択します。 「スケジュール式」 を選択します。
スケジュール式に 「rate(5 minutes)」 と入力します。
※5分毎に実行しますよの設定です。

あとは追加ボタンを押下すれば完了です。
定期実行されてもエラーにならないよう関数側を必要に応じて修正してください。パラメータなしで実行されるのでそれを判定に使っても良いかと思います。
これできっと何かが数秒早くなって世界のどこかで誰かが喜びます。