🤷‍♂️

Cloud functionsのcold start対策してたら、インスタンス数の上限に引っかかるってばようううう

2022/04/15に公開

選手入場

Cloud functionsのcold start対策してたら、インスタンス数の上限にちょこちょこ引っかかる&どうやら最近、cloud functionsにてインスタンス数の設定ができるようになったと噂を聞きつけ調べてみたので、まとめてみました。

メンバー表交換

普段、cloud functionsを触る機会が多いんですが、コールドスタート対策で、各functionsを定期的に呼び出す処理をしていました。しかしながら、ちょこちょこ以下のようなエラーが出ていました。
The request was aborted because there was no available instance.
うーん。そんなに致命的でも無いし、まあいっかと個人的には思っていたのですが、エンジニアたるもの、謎を謎のままにしておくのは良い性分とはいえません。なんとかしなければ!!

写真撮影

という感じだったのですが、調べてもあまりそのあたりに言及している記事は無いし、公式Doc見ても最大インスタンス数を超えるとfunctionを起動できないよしか書いてないので悲しかったです。それがほかしてしまっていた原因です。そんな折に、最小インスタンス数設定できるやん!!という鶴の一声が聞こえました。

そしてピッチへ

「だけども、一体それがなんだっていうだい?だって建てたれるインスタンスが足りないから困っているんじゃ無いのかい?」
「あ、ちょっと待って。あ、そうか。」

そもそも、コールドスタートとは使われていないfunctionのインスタンスが消えてから呼び出された時に起こる、インスタンスの起動が原因の遅延減少です。大体1s - 2sくらいです。
ファストな消費のみで形成されている現代社会においては1,2sは命取りですよね。
そこで脚光を浴びるのが最小インスタンス数の設定な訳です。各funcionごとに最小のインスタンス数を設定することで、消えて無くならないようにしてくれます。いいですね、この設定。控えめに言って最高じゃないですか?

キックオフ

解決はできそうとは言っても、結局何が起きていたのか気になったので、飛んでくるエラーログを半目で眺めていると、弊エラーに引っかかっているfunctionと引っかかっていないfunctionがあって、どうやらよく使われるものは引っかかってなくて、あまり使われていないfunctionは引っかかっているような感じでした。。。

むむむ、これはちゃんとモノを考える必要がありそうです。
困ったら、公式Docということでインスタンス周りについて何度目かわかりませんが見てみることにしました。
ふむふむ、以下のことがわかりました。

  • 最大インスタンス数は過剰なスケールアップを抑えるために設定する
  • 最大インスタンス数は任意の時点で共存するインスタンス数が上限を超えないようにするための制限
  • 上限を指定しない場合、Cloud Functionsはスループットの制限よりも需要を満たすためのスケールアップを優先するように設計されている

最大インスタンス数を指定する目的はわかりました。要するにGoogleの優しさなわけですね。
さすがDo the right thing.な会社ですね。いいぞ、もっとやれ。いや、やってください、お願いします。
しかしながらこのままでは、何が起こっていたのかわかりません。。。だって最大インスタンス数を設定していなかった場合のことが需要を優先するしか書かれていませんもの!!!

ハーフタイムというかティータイム

さて、ここからは考察になります。あくまでも一意見ですので、teaとcookieでも嗜みながら読んでいただければと思います。

後半戦

一旦ここまでの流れを整理しておくと、
コールドスタートをケアしたい
→ 定期的に呼び出せばいいんじゃね?
→ 😄The request was aborted because there was no available instance.
→ what the fxxk
という感じで、さらにあまり使われていないfunctionにのみ出てそうです。
となるとこれは、いい感じにスケールアップしてくれてるfnctionとそうでないfunctionが存在すると考えられます。定期的に呼び出すと言っても、そのfunction内で何かしてるわけでは無いですが(その時は)、一応アクセスはされているわけです。
なのでもし仮に例えば、よく使われているfunctionの最大インスタンス数は10と暗黙的に設定されている一方で、あまり使われていないfunctionの最大インスタンス数は1と暗黙的に設定されているとしたら?
定期的に叩くというとイメージが湧かないかもなんで、例えば1分ごとにアクセスだけするとしましょう。
あまり使われていないfunctionにアクセス
→インスタンス起動
→1分後に再度アクセス(を何回か繰り返すと)
→何らかの理由で1分間で処理しきれない
→起動できるインスタンスないよ!!最大インスタンス数に縛られているからね!!
=ガンダム(起動せんし)

とはならないでしょうか?何度もアクセスが来て、何らかの理由から前のリクエストを捌ききれていない状況になり、新たなインスタンスを起動しようとしても普段は捌ける程度のアクセスしか来てないので最大インスタンス数は大きくない。よって起動しようにも起動できない。ゆえに
The request was aborted because there was no available instance.が出る。
もちろん例として出した具体的な数値は、違うと思いますが、こんな可能性も無くはないような気がしてます。

そしてこのように、需要の大きなfunctionの最大インスタンス数は需要の小さなfunctionの最大インスタンス数よりも多く設定されていることが、スループットよりも需要を優先する設計ということなのではないでしょうか。(これを確かめるためにはスループットの大きなたまにしか呼び出されないfunctionとスループットは普通だけど、呼び出される頻度は高めのfunctionを用意して検証する必要がありますが。。。)

なので、まとめると最大・最小インスタンス数をデフォルトの0としていると、暗黙的に設定されたインスタンス数が作用して

  • インスタンスを立てることができない
  • インスタンスがない(コールドスタート)
    といった事象が起きていると考えられます。

アディショナルタイム

ちなみに、Google Cloudのrelease noteを見ると最小インスタンス数を設定できるようにしたβ版のリリースが2021年の8月30日から、一般リリースしたのが2021年12月7日からということらしいです。

また、こちらのGoogle Cloudの技術ブログでは(まあ自社製品に関するブログなのでアレですけど。。。)
3つのfunctionをCloud Workflowsで繋げたデモアプリを紹介しており、最小インスタンス数を設定しなかった場合と設定した場合を比べると、設定した場合は実行時間を11s削減できたようです。詳しくはブログを見ていただければと思いますが、2つのfunctionの実行時間をそれぞれ1.7s と 2.0sくらい減少させることができている箇所があるので、これがcold startであったと考えられます。

ここで、ホイッスルー

ということで、まとめると
・min-instanceを設定することは一定の効果が見込まれそう(当たり前の帰結)
・予想外の費用は無くすために、最大インスタンス数を設定すると良いかも

ということでした。

ユニフォーム交換

インスタンス数周りの設定に関して、AWS Lamdaは2019年の12月4日に、Azure functionsは2019年6月にリリース記事出しているのでCloud functionsは2年遅れということなりますね。
そういうとこやで、Google…..

Discussion