API Gateway + Lambda(Node.js) + MySQL(sequelize)の構成で、Lambdaの処理時間が2.5秒とだいぶ遅かったです。
その後色々手を加えて当初の32%の0.8秒にまで抑えることができたので対応内容をシェアします。
メモリ量調整
定番です。
当初256MBでした。増やせば増やすほど早くなりそうな感じでしたが、コストとの折り合いを見て1024MBに変更しました。
これで平均2.1秒と0.4秒減。
SSM Parameter Storeへの問い合わせを並列実行
コード内で4回Parameter Storeへ値を取得していたのですが、Promise.allを使って並列で取得するようにしました。
1回の値取得に50ミリ秒程度掛かっていたので、これで平均1.95秒と150ミリ秒減りました。
コードのイメージとしてはこんな感じです。
const [dbHost, dbName, dbUser, dbPass] = await Promise.all(
[
retrieveDbSetting('DB_HOST'),
retrieveDbSetting('DB_DATABASE'),
retrieveDbSetting('DB_USERNAME'),
retrieveDbSetting('DB_PASSWORD')
]
);
DBコネクションプールのアイドル時間を待たずすぐにレスポンスを返す (ほぼこれのおかげ)
Sequelizeの設定でpoolというものがあります。
コネクションプーリングの設定なのですが、自分はこれを設定していました。
この時Lambda関数はreturnで処理を終了させていても、コネクションプーリングの待機時間中はLambda関数が終わらないという事になっていました。
解決策としてはコネクションプーリングを削除するか(試してはいませんが)、イベントループ終了を待たないという下記設定をLambdaに書けば大丈夫です。
context.callbackWaitsForEmptyEventLoop = false;
npmのdevDependencyをインストールしないようにする
時間の計測はしていなくて微々たるものだとは思いますが一応…。
普通にnpm install
するとdevDependencyもインストールされてしまいます。
これを防ぐにはnpm install --production
とするか、環境変数としてNODE_ENV=production
を定義します。
今回は開発・ステージング・本番環境と同じやり方でパッケージを入れたかったので、後者の環境変数で切り替えました。