Cloud Run の最小インスタンス数: サーバーレスのコールド スタートの最小化
Google Cloud Japan Team
※この投稿は米国時間 2020 年 12 月 10 日に、Google Cloud blog に投稿されたものの抄訳です。
サーバーレスの長所の一つは、サービスを 0 にスケールダウンできる従量課金制の運用モデルです。しかし、特定のクラスのアプリケーションの場合、サーバーレスに関してあまりありがたくない点があります。それは、0 にスケールダウンした結果、アプリケーションの再ウェイクアップ時に最初のリクエストの処理でレイテンシが発生することです。この起動時のレイテンシは、サーバーレスにとって新たな問題です。サーバーレスは、その名が示すように、アプリケーションがトラフィックを受け取っていない場合、サーバーを一切実行しないものであるためです。
本日は、Google のマネージド サーバーレス コンピューティング プラットフォームである Cloud Run の最小インスタンス数という機能をご紹介します。この重要な新機能は、アプリケーションのパフォーマンスを大幅に改善する可能性があります。そして結果的に、レイテンシの影響を受けやすいアプリケーションもサーバーレス コンピューティング プラットフォームのメリットを享受できるように、Cloud Run 上で実行できるようになります。それでは詳しく見ていきましょう。
コールド スタートの削減
この機能を使用すると、スタンバイ状態でトラフィック処理の準備が整った Cloud Run インスタンスの最小数を構成できます。これにより、最小限のコールド スタートでサービスがリクエストへの対応を開始できます。
Cloud Run の新機能である最小インスタンス数を使用するには、シンプルな gcloud コマンドまたは UI で Cloud Run サービスの最小インスタンス数を構成するだけです。
構成後、指定された最小数のインスタンスがアプリケーションのトラフィック処理を待機するようになるため、アプリケーションのコールド スタートを最小限に抑え、レイテンシの影響を受けやすいアプリケーションを Cloud Run 上で実行できるようになります。
ブートストラップ ロジックの再利用
Cloud Run の最小インスタンス数は、コールド スタートを最小限に抑えるだけでなく、データベース接続の開始や Cloud Storage からメモリへのファイルの読み込みなどの主要なオペレーションのブートストラップ時間の削減にも役立ちます。ブートストラップ時間を低減することで、リクエストのレイテンシをさらに減らすことができます。これは、ブートストラップ ロジックを 1 回実行するだけで、指定した最小インスタンス数の複数のリクエストでもそれを利用できるためです。
以下の golang サーバーレス関数は、ブートストラップ ロジックを 1 回実行し、それを指定した最小インスタンス数全体で再利用する方法を示しています。
ブートストラップ ロジックを 1 回実行し、最小インスタンス数全体で再利用する
低コストでサーバーレスのメリットを享受する
Cloud Run の最小インスタンス数は、インスタンスの最小数を設定するだけではありません。インスタンスにスロットルした CPU も構成できるため、非常に低コストでこの機能を利用できます。つまり、サーバーレスの効率とコスト面での利点を活かしながら、レイテンシの影響を受けやすいワークロードをサーバーレスに移行できるという 2 つのメリットを同時に得られます。
Cloud Run の最小インスタンス数の活用例
ここまで Cloud Run の最小インスタンス数がもたらすメリットとこの機能の使い方についてご説明してきましたが、実際にはどのように動作するのでしょうか。また、なぜこの機能を利用すべきなのでしょうか。
サーバーレス プラットフォームは従来、ゼロにスケールすることがメリットになるアプリケーションを対象としてきましたが、ブートストラップ期間中のコールド スタートによるレイテンシの影響を受ける最初の応答時間に関しては、ある程度の妥協が必要です。この点は、新規に開発し、ソースと実行時の動作を完全に制御できるアプリケーションについては問題になりません。しかし、従来のサーバーレスのアプローチが適しているとは言えない既製のアプリケーションもあります。指標収集のための Prometheus やポリシー決定のための Open Policy Agent(OPA)などのカスタム コントロール プレーンについて考えてみましょう。通常、これらのコントロール プレーンでは最初の起動時に高度な構成と多少のブートストラップが必要であるため、レイテンシの増加を許容できません。
例えば、OPA を起動すると、通常はリモートのソースからポリシーをフェッチしてキャッシュに保存し、その後のポリシー決定をスピードアップします。一般的なサーバーレス環境では、OPA などのコントロール プレーンはゼロにスケールするとパフォーマンス ヒットが生じ、重要なユーザー トランザクションのリクエストパスに留まるため、再起動してポリシー リクエストを処理します。
Cloud Run の最小インスタンス数を使用すると、この問題に事前に対処できます。ゼロにスケールして、各リクエスト間でポリシー エンジンをブートストラップするのではなく、各リクエストを OPA の「ウォーム」インスタンスで処理できるようになります。
この実際の例を見てみましょう。次のセクションでは、OPA を中央のコントロール プレーンとしてデプロイし、パフォーマンス要件を満たすように最小インスタンス数を設定します。
実行時に Cloud Storage バケットからポリシー バンドルを pull するように OPA サーバーを構成します。これにより、クエリが実行されると、“/health” HTTP パスの http GET リクエストが可能になります。以下に、OPA ポリシーがどのようになるかを示します。
ポリシーはポリシー バンドルにパッケージングされ、Cloud Storage バケットにアップロードされます。しかしまずは、いくつかの依存関係をブートストラップする必要があります。詳しくは、こちらのブートストラップ プロセスに関するチュートリアルをご覧ください。シンプルに説明するために、ヘルパー スクリプトを利用します。
min-instances-tutorial ディレクトリに移動します。
OPA Cloud Run インスタンスをデプロイする前に、以下の作業を行う必要があります。
OPA サービス アカウントを作成する
OPA ポリシー バンドルを保存する Cloud Storage バケットを作成する
OPA ポリシー バンドル(bundle.tar.gz)を Cloud Storage にアップロードする
OPA バンドルにアクセスする権限を OPA サービス アカウントに付与する
この時点で、OPA をホストするためのすべての依存関係が定まります。ここでは「gcloud」コマンドを使用して OPA をデプロイします。バケット名とサービス アカウントのメールアドレスは、前のステップで実行したブートストラップ スクリプトによって作成された「.env」ファイルに保存されます。
$ source .env
open-policy-agent Cloud Run インスタンスを作成します。
以下は、このコマンドからの出力です。環境のブートストラップが成功したことがわかります。
ここで初めて OPA サーバーが起動し、Cloud Storage からポリシー バンドルをダウンロードしてキャッシュに保存します。ただし最小インスタンス数のおかげで、この動作は 1 回で済みます。
これで、ポリシー決定のテストの準備が整いました。これには curl を使用できます。open-policy-agent Cloud Run URL を取得します。
一連の入力により OPA サーバーに対してクエリを実行し、Cloud Storage に保存されているポリシー バンドルに基づいたポリシー決定を取得します。
以下がレスポンスです。
ここで数分間待てば、OPA がゼロにスケールせず、プロセスがバックグラウンドで停止して、次のリクエストがインスタンスにヒットした場合にのみ再開される様子を見ることができます。この点が料金にどのような影響を及ぼすかについて詳しくは、料金のページをご覧ください。
最小インスタンス数でアプリケーションの最大の可能性を引き出す
一見しただけでは、Cloud Run の最小インスタンス数は重要な機能とは思えないかもしれません。しかし Google では、この機能を使用することで、より多くの既製アプリケーションを、よりコスト効率が高い形でサーバーレス モデルで実行できるようになり、サーバーレス コンピューティングが抱える「妥協」を解消できると考えています。Cloud Run を初めて使用する場合は、こちらのクイックスタートをご覧ください。
-デベロッパー アドボケイト Kelsey Hightower
-プロダクト マネージャー Vinod Ramachandran