サーバーレス コンテナ Cloud Run に待望の新機能 Always on CPU が登場しました

Shingo
google-cloud-jp
Published in
7 min readSep 14, 2021

--

TL;DR

  • Cloud Run で Always on CPU (プレビュー)が選択可能に
  • コンテナインスタンス起動中は CPU がフルに利用できます
  • 利用形態によっては料金面でメリットも

Cloud Run とは

ひとことでいうと「サーバーレス コンテナ」を提供するフルマネージドコンピューティング環境であると言えます。コンテナ上のアプリケーションは、HTTPS、gRPC、WebSocket または イベントでトリガー されます。
処理した分だけ課金される サーバーレスサービスで、無料枠もありお手軽に利用を開始することができます。
また大規模なサービスにも多くの実績がある大変人気のサービスです。

Always on CPU (プレビュー)

従来、Cloud Run では リクエストを受け付け処理している間のみ CPU の割当てが保証されていました。つまりレスポンスを返したあとは CPU 割当てが無効になるか、厳しく制限されます。そのため、レスポンス後の処理 には向いていませんでした。例えば非同期処理 を手軽に利用できる Go やNode.js などの利用には注意が必要だったと言えます。

今回プレビューリリースされた Always on CPU を利用すると、コンテナインスタンスが存在する間は CPU が割当てられます。つまりリクエストを受け付けてレスポンスを返したあとでも、またリクエストがない状態でも、処理を実行することができます。

ユースケースとしてはまず、Go の Goroutines や Node.js の async などの非同期処理や非同期ジョブの利用が挙げられます。
Web / API のサービスでは時間がかかる処理を非同期にして、レスポンスをできるだけ速くクライアントに返す手法がよく使われています。後回しにしたい処理としては、Pub/Subへのメッセージ送信や、データ加工したファイル を Google Cloud Storage へ送信する、などが考えられますね。Always on CPU はこういう用途にピッタリはまります。
その他にも、バックグラウンドでの メトリクス送信、Firestoreの変更をリッスンさせる、など様々なユースケースが考えられます。

またこれに伴い、新しい料金プラン も用意されました。
(現時点では英語のページをご確認ください。)

  • 従来はリクエスト課金 100万リクエスト単位で $0.40 (最初の200万リクエストは無料)だった部分がなくなります。
    リクエストはいくつ受け付けても課金対象になりません。
  • コンテナインスタンスが起動している時間全てが課金対象となります。
    CPU、メモリ料金の単価は 非 Always on CPU に比べて それぞれ 25%、15% 程度割安 に抑えられています。
  • ネットワーク料金については変更ありません。

リクエスト課金がなくなりますので、利用状況によってはコストを抑えることができる可能性があります。
特に、常時一定量のリクエストを受け付けている Web サイト や APIサービスなどでは大きなコストメリットがでるかもしれません。
従来の Cloud Run と Always on CPU のどちらがお得になるかはアクセス量/パターンやユースケースによって異なりますので、慎重に選択してください。(変更はいつでも可能です。)

なお Always on CPU のプレビュー機能は、Cloud Run がサポートされている すべてのリージョンでご利用になれます。

合わせて ブログ記事(英語)も御覧ください。
https://cloud.google.com/blog/products/serverless/cloud-run-gets-always-on-cpu-allocation

挙動の確認

従来の Cloud Run と Always on CPU を有効化した Cloud Run の挙動を実験してかんたんに比較してみたいと思います。

Go で検証プログラムを用意して、2つのAPIを作ってみました。

  • /loop
    リクエストを受付け、非同期処理であるGoroutines を呼び出したあと、すぐにレスポンスを返します。
    Go routine では、無限ループで CPUバウンドな処理(フィボナッチ数列計算、ローカルのMacで1回 1秒程度)を実行し、一定数ごとにログを出力します。
    処理に意味はないのですが、どのくらいCPUをフルで使えるか、比較の指標になればと思います。
  • /storage
    リクエストを受付け、非同期処理であるGoroutines を呼び出したあと、すぐにレスポンスを返します。
    Go routine では、ローカルのファイル(/etc/services)を20回、Google Cloud Storage にアップロードします。ネットワーク的なI/Oバウンドの処理と言えますが、実際に使われるような Cloud Storage 連携のユースケースにはどう影響するか、見てみたいと思います。

Cloud Run では、コンテナインスタンスの終了時にSIGTERM を発行しますので、これを利用してインスタンスが起動している長さも記録します。

なお、Always on CPU のデプロイは GCP コンソールでも可能ですが、gcloud コマンドだと — no-cpu-throttling オプション を付与することでデプロイ出来ます。以下はコマンド例です。
( Dockerfile を書かずに一発デプロイ する例です。)

gcloud beta run deploy --source=. --no-cpu-throttling always-on-cpu-test

必要に応じて事前に下記コマンドを実行して、gcloud コマンドをアップデートしてください。

gcloud components update

結果 /loop

  • 従来の Cloud Run
    実行回数 10 回
  • Always on CPU
    実行回数 660 回

どちらのインスタンスも、レスポンス返却後 約15分で停止しています。

従来の Cloud Run はレスポンスを返したあとに、ほとんどCPU が利用できず、10回しか実行ができなかったことがわかります。
その反面、Always on CPU では元気よく CPUが動いていたようで、リクエスト後 最大15分 SIGTERM を受け取るまで処理が動き続けています。

CPU 割当ての様子 です。
青い線が Always on CPU、下の方にぎりぎり見える緑の線が 従来の Cloud Run です。

結果 /storage

  • 従来の Cloud Run
    20回 アップロードの所要時間 32秒
  • Always on CPU
    20回 アップロードの所要時間 約0.8秒

同じく、どちらも 約15分で停止しています。

従来のCloud Run はレスポンスを返したあとに CPU の制限がされているものの完全に停止したわけではなく、時々 CPU を使ってファイルのアップロードを実行しています。
Always on CPU はほぼ一瞬で 20 ファイルをアップロードできているので レスポンス返却後も CPU が活用できている様子が見て取れます。

もっと長く実行したい場合は

実験ではレスポンスの返却後、約15分でインスタンスが停止していましたが、もっと長く処理を続けたい場合はどうしたらよいでしょうか。

これには、最小インスタンスの設定 が利用できます。
https://cloud.google.com/run/docs/configuring/min-instances
最小インスタンスを必要数設定しておけば、設定したインスタンス数が常時維持されます。
これにより、さらに長時間のジョブを実行することができます。
(ただし、同じインスタンスが常に動き続けることを保証するものではありませんのでご注意ください。)

最小インスタンスの維持には別途 料金がかかりますので、設定前にご確認ください。

いかがだったでしょうか。

Always on CPU の機能は、これまで Cloud Run では対応が難しかった 非同期処理 / ジョブや、常時大量のリクエストを受け付けてコストがかさんでいるような Web サイト / API サービス などに対応できる可能性があります。
現時点ではプレビュー であることに注意して、お試しいただければと思います。

お手軽さを維持しながらどんどん成長する Cloud Run からますます目が離せませんね!

--

--