🎃

Cloud Functionsのパフォーマンス問題にどう立ち向かうのか

2022/02/02に公開

前書き

モバイルアプリのバックエンドにCloud Functions(for firebase)を使っていたときの話です。
諸々のデプロイ作業が終わって、アプリの動作確認していると、レスポンスが異常に遅いことが問題になりました。
コンソール上で各関数のパフォーマンスを調べてみたところ、1つの処理に4秒ほどかかっていたことが判明。この問題に立ち向かうべく、調査をしました。

Cold Start問題

Cloud Functionsは、1つのリクエストに対して、1つのインスタンスが作られ、そこで関数の処理が実行されます。インスタンスが作成されると、実行環境の初期化が行われ、その分の時間がかかってしまう。
1度インスタンスが作成されると、一定時間はそのインスタンスは維持され、再びその関数にリクエストがあった場合、インスタンスは再利用される。そのため、最初のリクエストよりも実行時間は少なくて済む。
ところが、関数がしばらく実行されないと、そのインスタンスは削除されてしまう。その後、再びリクエストがあったタイミングで、新しいインスタンスが作成される。新しいインスタンスが作成されると、実行環境はゼロから構築されるため、その分レイテンシが発生する→コールドスタート

Cloud Start問題への対応策

適切なリージョンに設定する

Cold Startとあまり関係ない気もするが、一応。
適切なリージョンに配置することで、レイテンシの改善が見込める。
今回は、日本で公開する予定のアプリであり、Cloud Functionsを含めた全てのリソースを、東京リージョンで設定しているため、問題にならないはず。

不要な依存モジュールが読み込まれないようにする

https://cloud.google.com/functions/docs/bestpractices/tips#use_dependencies_wisely
Cold Start時に、関数実行に使用しないモジュールまで読み込みされてしまうと、その分レイテンシが発生してしまう。そのため、Gincoさんの記事を参考にさせていただき、実行する関数のモジュールのみをロードするように修正。すごく勉強になりました。
https://tech.ginco.io/post/ginco-engineer-meetup-2018-cloud-functions/#cold-startの改善

min instancesを使う

https://cloud.google.com/functions/docs/configuring/min-instances
上記ドキュメントを参照。
最小インスタンスを設定してしまうと、その分料金が発生する。今回は予算の関係上、利用は厳しい。残念。

メモリの割り当て量を増やす

https://techlife.cookpad.com/entry/2019/07/05/100000
クックパッドさんの記事を参考にさせていただきました。これまた大変勉強になりました。

今回、Cloud Functionsの関数内で、Firestoreとのやりとりがあるが、Firestoreへの最初のリクエスト時には、新規にコネクションを貼る処理が発生する。Cloud Functionsの新しいインスタンスが立ち上がるたびに、Firestoreとの新規コネクション生成が発生するので、その分さらに時間がかかる。
色々と調査した結果、コネクションの確立を早くするためには、メモリの割り当てを増やすといいとのこと。当初、メモリの割り当てはデフォルトの256MBで、コールドスタート時の実行時間は4.5秒ほどかかっていた。メモリ使用量を見ても、それほど問題に思えなかったので、それに紐づいているCPUの割り当てが原因だと思う。メモリの割り当て量を512MBに増やしたところ、コールドスタート時の実行時間は2.2秒となった。さらに、1024MBに増やすと、1.3秒にまで改善した。

ただし、注意点として、メモリの割り当てを増やすと、それに応じて料金も上がるので、コストとパフォーマンスを天秤にかけて、よく考える必要がある。

参考文献

この記事は、以下の情報を参考にさせていただきました。大変勉強になりました。
https://tech.ginco.io/post/ginco-engineer-meetup-2018-cloud-functions/
https://techlife.cookpad.com/entry/2019/07/05/100000
https://cloud.google.com/functions/docs/bestpractices/tips#use_dependencies_wisely
https://cloud.google.com/functions/docs/configuring/min-instances

Discussion