...
Back

コールドスタートはパフォーマンスのバグではなく、価格設定上の判断である

スケールトゥゼロはプラットフォームの特性ではありません。それはダイヤルであり、それをデフォルトのままにしておくと、あなたの最も遅いリクエストのコストを他の誰かが決めることになります。

コールドスタートはパフォーマンスのバグではなく、価格設定上の判断である

コールドスタートは価格決定の問題である❄️

どのサーバーレス移行プロジェクトにも、最初の1リクエストを高速化しようと午後の時間を費やす場面があります。イメージを削り、重いモジュールを遅延ロードし、データベースクライアントをモジュールスコープの外に移動させる。これらはすべて、実際に効果のある本物の作業ですが、そのすべてが間違った変数を最適化しているのです。

最初の1リクエストが遅いのは、何も実行されていなかったからです。これはパフォーマンスのバグではありません。scale-to-zeroを受け入れたときにあなたが求めた挙動そのものであり、それには支払うだけで解決できる対価が伴います。


あなたが実際に交換しているもの

scale-to-zeroとは、こういうことです。誰も使っていないときはコストがゼロになり、それを起動した人が起動コストを支払う。

多くのワークロードにとって、これは実に良いトレードオフです。社内ツール。ステージング環境。1日に9回発火するWebhook。ユーザーが自分自身であるか、リクエストがバックグラウンドで実行されるため最初の2秒のレスポンス遅延が問題にならないような、あらゆるケースです。

プロダクトのトップページにとっては、これは悪いトレードオフです。2秒が耐えられないからではありません。そのコストを誰が支払うのかが問題なのです。あなたのコールドスタートの影響を受けるのは、リンクからやってきた初回の訪問者である場合が圧倒的に多いのです。つまり、あなたが最もコストをかけて獲得し、最も少ない情報であなたを評価しようとしているトラフィックです。このコストは本物であり、最悪の場所で発生します。


最適化の前に、まず計算を

有用な手は、起動を速くすることではありません。1つのインスタンスをウォーム状態に保つコストが実際にいくらかを調べることです。なぜなら、その数字は、それを回避するための最適化に費やす労力と比べると、馬鹿らしいほど小さいことが多いからです。

概算:

warm baseline ≈ (instance memory × instance count) × hourly rate × 730

常に1つのインスタンスをウォーム状態に保つ小さなサービスの場合、これは月額数ドル程度に収まることがよくあります。それを、あなたがモジュールのインポート構造を変更するために費やそうとしていた午後の時間と、そしてタブを閉じてしまう訪問者と、比べてみてください。

この計算が飛ばされがちな理由は、min instances = 0がデフォルトであり、デフォルトは意思決定のように感じられないからです。しかし、それは紛れもなく意思決定であり、テンプレートを書いた誰かによって、あなたに代わって下されているのです。


それでもコールドスタートの最適化が正しいとき

ウォーム状態を維持するためにお金を払っても、コールドスタートがなくなるわけではありません。ただ、発生頻度が低くなるだけです。トラフィックのスパイクは依然として新しいインスタンスを立ち上げ、それらのインスタンスはやはりコールドスタートします。ですから、起動パスには注意を払う価値があります。ただし、パニックになるほどの注意は不要です。

本当にレバレッジが効く変更は、次の順です。

  1. モジュールスコープで何にも接続しない。 インポート時に構築されるデータベースやキャッシュのクライアントは、依存先がすでに高負荷で苦しんでいるスパイク時のものも含め、すべてのコールドスタートでハンドシェイクを待たせてしまいます。
  2. より小さなイメージをデプロイする。 Pullにかかる時間は起動時間の一部です。ここで、マルチステージビルドや軽量化された出力フォーマットが、レジストリのコストとレイテンシーという2つの面でその価値を発揮します。
  3. 重いインポートは、それを必要とするルートに遅延させる。 めったに使われない1つのエンドポイントが巨大な依存関係を読み込むと、すべてのコールドスタートがその代償を払うことになります。
  4. concurrencyを意図的に設定する。 1つのインスタンスが処理する同時リクエスト数は、新しいインスタンスを立ち上げる頻度を決定します。低すぎると、わずかな負荷でも常にコールドスタートが発生します。高すぎると、1つの遅いリクエストが他のリクエストをブロックしてしまいます。

注意してほしいのは、これらのいずれも遅延をゼロにはしないということです。これらはテールの遅延を縮小させるものです。一般的なケースでの遅延をなくすのは、(インスタンスをウォームに保つ)設定です。


心に留めておくべき考え方

インフラのデフォルト設定は、請求書付きの意見です。scale-to-zero、リクエストのconcurrency、インスタンス数の上限、ログの保持期間。これらはすべて、誰かが「誰かにとって」妥当な値を選んだ調整ノブであり、どれも自らが選択肢であることを主張してはきません。

報われる習慣は小さなことです。あなたが受け継いだ各デフォルト設定について、それがあなたに何を犠牲にさせ、それを変更すると何がかかるのかを、一文で言えるようにしておくことです。すべてを変更するためではありません。ただ知っておくためです。そうすれば、次に遅い初回リクエストがあなたを丸一日がかりのモジュール改修へと向かわせたとき、その答えが設定ファイルの一行と5ドルで済むかどうかを確認できるのです。