Google Cloudで理解するサーバーレス・アーキテクチャ

記事タイトルとURLをコピーする

当記事は みずほリサーチ&テクノロジーズ × G-gen エンジニアコラボレーション企画 で執筆されたものです。

サーバーレス構成ではクラウドサービスのポテンシャルを最大限引き出すことができます。モダンなアプリケーションの設計にはサーバーレスへの理解が必須であり、あらためて整理することにしました。


G-gen の佐々木です。当記事ではクラウドサービスにおける サーバーレス・アーキテクチャ について、Google Cloud のプロダクトを例に解説します。

サーバーレスの概要

サーバーレス・アーキテクチャとは

サーバーレス・アーキテクチャ (サーバーレスコンピューティング) とは、Google Cloud (旧称 GCP) のようなクラウドプロバイダが所有している CPU やメモリ、ストレージなどの膨大なリソースの一部を、サービス利用者が 必要なときに必要な量だけ利用し利用したぶんだけ料金を支払う 方式で提供されるサービスのアーキテクチャを指します。以下、単にサーバーレスと呼称します。

代表的なプロダクトとして Amazon Web Services (AWS) の AWS Lambda や、Google Cloud の Cloud Functions、Cloud Run 等の開発者向けサービスがあります。また Google Cloud の BigQuery に代表されるように、データベースなどのサービスを基盤を意識することなく利用できるようなサービスも、サーバーレスであるとされます。

つまりサーバーレスという言葉は、サーバリソースを意識せずに利用できるようなサービス全般を指します。

サーバーレスとその基盤

用語の定義

用語の定義にも触れておきます。クラウドネイティブを推進するための非営利団体 Cloud Native Computing Foundation (CNCF) は、サーバーレスという言葉の定義を「FaaS、および API サービスとして提供される BaaS の双方あるいは一方を意味する言葉」としています。

定義にある FaaS および BaaS は、以下のようなサービスを指します。

サーバーレスの種類 説明 該当する Google プロダクト
FaaS (Function as a Service) イベントドリブンコンピューティングを提供する。
利用者はイベントや HTTP リクエストによってトリガーされる 関数 を利用して、アプリケーションコードを実行できる。
・Cloud Functions (コンピューティング)
BaaS (Backend as a Service) 認証やデータベースなどのアプリケーションのサブセットとなる機能を API 経由で提供する。 ・Firebase (データベース、認証ほか)
・Cloud Endpoints
・Cloud Run (コンテナ用プラットフォーム)
・BigQuery (分析用データベース)

サーバーレスの特徴

メリットとデメリット

サーバーレスの特徴は大きく 3 つあり、それぞれメリットとデメリットは以下のようになります。

特徴 メリット デメリット
インフラリソースのプロビジョニング・運用管理が不要 インフラ構築・運用の負荷を削減 構成の柔軟性が低い
動的なスケーリング ・キャパシティプランニングが不要
・ゼロスケールによるコスト削減
コールドスタートによる即応性の低さ
従量課金制 リソースに対するコスト効率が良い コスト予測がしにくい

特徴① インフラリソースのプロビジョニング・運用管理が不要

インフラを意識しない

サーバーレス (Serverless) と書くとサーバーが存在しないように思えますが、実際にはクラウドプロバイダのデータセンターには物理的にサーバーが存在しています。

サーバーレスとは、実際には利用者が サーバーの存在を意識しなくてもよい ことを意味しています。コードやコンテナイメージなどを用意するだけで、それを動かすインフラのプロビジョニングや運用管理はクラウドプロバイダに任せることができます。

なお「プロビジョニング」という用語はサーバーリソースを割り当てて仮想サーバーなどのインフラリソースを作成することを指しており、「予め構築しておく」のようにイメージしておけば問題ありません。

サーバーレスの利用者は、バックアップや冗長化などの耐障害性の考慮や、OS やミドルウェアのパッチ適用などに労力を費やす必要がなくなり、アプリケーションの開発に集中することができます。

柔軟性は劣る

このようなメリットのトレードオフとして、サーバーレスではアプリケーション実行環境に対する自由度はある程度制限されます。

たとえば Google Cloud の FaaS である Cloud Functions では、使用できる開発言語やコードの実行時間、同時実行数などの制限があり、IaaS である Compute Engine (GCE) と比較すると、インフラ構成の柔軟性は劣ります。

利用者の責任範囲

次の図は Google Cloud のドキュメント からの引用で、クラウドプロバイダと利用者の責任共有範囲を示したものです。サーバーレスの責任共有範囲は "SaaS" の列を見ればよいとお考えください。

サーバーレスは、アプリケーションロジック (Content) とリソースに対するアクセス制御 (Access policy) 以外の管理をクラウドプロバイダに任せることができます。

リソースに対するクラウドプロバイダと利用者の責任範囲 ( Google Cloud ドキュメントより引用)

特徴② 動的なスケーリング

動的リソース確保とゼロスケール

サーバーレスでは必要に応じてインフラリソースが動的にスケーリングされるため、リソース量を事前に計画する必要がありません。

高負荷でリソースが足りなくなれば自動で追加 され、処理が完了して 不要になったリソースは自動的に解放される というように、待機状態のリソースがなくなるように動作します。

これにより、利用者が何もしなくても、アプリケーションに対する不測のリクエスト増加に対応できるほか、過剰にリソースを確保することによる料金の増加を抑えることができます。

特に重要な点として、サーバーレスでは処理を全く行っていないとき、リソースをゼロまでスケーリングすることができます (ゼロスケール)。

後述の従量課金の特徴と合わせ、何も処理を行わないときはリソースの使用料金をゼロに抑えることができます。

コールドスタート

スケーリングにおけるこのような特徴のデメリットとして、コールドスタート によるレイテンシの増加があります。

リソースがゼロスケールされている状態でアプリケーションに対してリクエストが送信されると、まずリソースを確保し、アプリケーションを実行する準備ができてから実際の処理が行われるため、リクエストに対する即応性が損なわれます。

特徴③ 従量課金制

コストメリット

Compute Engine のような IaaS や Google Kubernetes Engine (GKE)、Cloud SQL のようなマネージド型のクラウドサービスのうち「インスタンス」「ノード」といったリソースで仮想サーバーが事前にプロビジョニングされるサービスでは、使用するリソース量を事前に確保するので、何も処理を行っていなくても リソースが確保されている間は課金される のが基本的な仕組みとなっています。

それに対してサーバーレスでは、確保したリソースではなく 実際の処理でリソースを使用したぶんだけ課金される 仕組みとなっています。アプリケーションが実行されている時間や、リクエストの回数などに応じて料金が発生します。

課金の仕組みの例

Google Cloud の代表的なサーバーレスプロダクトの料金設定は以下のようになっています。

プロダクト 課金対象 無料枠
Cloud Functions ・CPU、メモリを実際の処理で使用した時間
・呼び出し回数
・外向きのネットワーク転送データ量(インターネット or 別リージョン宛の転送)
・毎月 200,000 GHz 秒 (CPU)、400,000 GB 秒(メモリ)まで無料
・毎月 200 万回まで無料(呼び出し回数)
・毎月 5 GB まで無料(ネットワーク)
Firebase
(例:Firestore)
・実際に保存したデータ量
・外向きのネットワーク転送量
・書き込み操作の回数
・読み取り操作の回数
・削除操作の回数
・毎月 1 GiB まで無料(データ量)
・毎月 10 GiB まで無料(ネットワーク)
・1 日 2 万件まで無料(書き込み)
・1 日 5 万件まで無料(読み取り)
・1 日 2 万件まで無料(削除)
Cloud Endpoints ・API の呼び出し回数 ・毎月 200 万回まで無料
BigQuery ・クエリによって処理されたバイト数
・ストレージに保存されたデータ量
・毎月 1 TB まで無料(クエリ料金)
・毎月 10 GB まで無料(ストレージ料金)
Cloud Run ・CPU、メモリを実際の処理で使用した時間
・呼び出し回数
・外向きのネットワーク転送データ量(インターネット or 別リージョン宛の転送)
・毎月 180,000 vCPU 秒 (CPU)、360,000 GiB 秒(メモリ)まで無料
・毎月 200 万回まで無料(呼び出し回数)
・毎月 5 GB まで無料(ネットワーク)

表に記載したように、サーバーレスのプロダクトは無料枠が豊富に提供されており、単純な処理であれば無料枠の範囲にすべて収めることも可能です。

料金予測の難しさ

サーバーレスの従量課金制のデメリットとして、コスト予測がしにくい 点が挙げられます。

あらかじめ確保したリソースで料金を計算できる IaaS などと異なり、サーバーレスの料金は実際にどれだけ処理が行われるかに依存するため、運用を始める前にコストを見積もる難易度が高くなります。

ユースケース

サーバーレスに適した処理

ここまで解説したサーバーレスの特徴により、以下のような用途でサーバーレスを活用することができます。

  • 1回の処理時間が短い処理
  • 常時動いているわけではなく、いつ呼ばれるか分からない処理

具体的には、以下のような処理が、サーバーレスに向いていると言えます。

  • アクセス量が小さいウェブサイトのバックエンド処理
  • データベースの変更 (挿入、更新、削除) をトリガーとしたロジックの実行
  • ETL (ELT) ジョブの実行
  • チャットボットのバックエンド処理
  • スケジュールされたバッチジョブの実行
  • 機械学習モデルのホスティング

Google Cloud プロダクトでの例

Cloud Functions や Cloud Run は、HTTP リクエストから直接呼び出せるほか、Eventarc や Pub/Sub との統合により、各種イベントをトリガーとした呼び出しができます (イベントドリブン)。

Cloud Scheduler との統合により、cron ジョブを用いた関数の定期呼び出しが可能となっており、一定時間に収まるバッチ処理にも適しています。

また Cloud Run では、運用負荷を最小限に抑えながらウェブアプリケーションをホスティングしたり、機械学習で生成したモデルをコンテナイメージに含めてデプロイすることで、モデルを用いたオンライン予測 API をサーバーレスで実装したりできます。

サーバーレスに向かないパターン

アプリケーション実行環境に特有の要件があるケース

サーバーレスではクラウドプロバイダにリソースの運用管理を任せることができる代わりに、アプリケーション実行環境の構成が制限されます。

例えば Cloud Functions はコードをアップロードするだけで利用することができますが、開発言語の種類やバージョンに制限があります。

Cloud Run ではアップロード対象がコンテナイメージとなるため、構成の柔軟性はかなり高まりますが、2023年5月現在で GPU がサポートされていないため、GPU を用いた処理を実装する場合は Compute Engine や GKE を利用する必要があります。

また、これらのサーバーレスコンピューティングのプロダクトは、アプリケーション実行の際に確保できる CPU やメモリの上限が Compute Engine よりも低く設定されています。

リクエストに対する即応性が求められるケース

リソースがゼロスケールされている状態からリクエストを処理する場合、コールドスタートにより、常時リソースを確保している非サーバーレスの実装よりもレイテンシが劣る場合があります。

コールドスタートによるレイテンシの増加

ただし、対策はあります。Cloud Run ではコールドスタートの対策として、最低限のリソースを常時確保しておくような設定ができます。この場合は当然ながら、ゼロスケールによるコストメリットとトレードオフです。

さらに Cloud Run では Startup CPU boost という機能があり、ある程度の追加課金によりコールドスタート時のパフォーマンスを改善するオプションも用意されています。これらの対策により、ゼロスケール時のレイテンシ問題はある程度対策可能です。

リクエストを常時受信するケース

リソースの使用時間、および呼び出し回数に比例して料金が発生するサービス仕様上、アプリケーションに対するリクエストを常時受信するようなケースでは、IaaS や非サーバーレスのマネージドサービスを用いたほうが、リソースの 確約利用割引 などによるコストメリットが得られる可能性があります。

サーバーレスを用いたシステム構築時の注意点

ステートレスな実装

ステートレスな実装

動的スケーリングの特徴により、サーバーレスで構築するアプリケーションは、処理が内部でステート (状態) を持たない、つまり ステートレス な実装にすることが求められます。

セッション情報などのステートや永続化するべきデータは、スケーリングの際に失われないよう、外部のデータストアに保存するようにアプリケーションを設計します。

ステートレスな実装

上記の図は一例です。以下に、その意義を解説します。

セッション情報の外部への保存

例えば、サーバーレスなコンテナ実行環境が提供される Cloud Run で Web アプリケーションをホストする場合、リクエスト量に応じてコンテナの動的スケーリングが行われ、同一クライアントからのリクエストが、常に同じコンテナに送られる保証はありません

そのためセッション情報などの一時データは、外部のインメモリデータベース等に保存するケースが多くなります。Google Cloud ではインメモリ DB である Redis や Memcached をホストするためのマネージドサービスである Cloud Memorystore が用意されています。

なお参考情報として、Cloud Run にはベストエフォートの セッションアフィニティ機能は用意されていますが、主にキャッシング用途のための機能でありコンテナをステートフルにするための機能ではありません。

データの永続化

動的スケーリングによりリクエストが少ない場合にスケールインが行われる、つまりコンテナが破棄されるため、永続化する必要のあるデータは コンテナ側に保存することができません

永続化する必要のあるデータは Cloud SQL (マネージドの RDBMS) や Cloud Storage (オブジェクトストレージ) に格納するなど、Cloud Run のコンテナ側でデータを保持しないようにアプリケーションを設計します。

べき等性を考慮した実装

べき等性 (冪等性) とは、ある操作を 1 回行っても複数回行っても結果が同じである性質のことです。

たとえば Cloud Functions のような FaaS では、最大リソース量や実行時間の制限があることから、1 つの Cloud Functions 関数でアプリケーションのすべての処理を行うのではなく、複数の小さな処理ごとに関数を作成する マイクロサービス の形式で処理を実装します。

一連の処理フローを複数の関数で実装する場合、フローの途中で問題が発生した場合のキャンセル (ロールバック) 処理が複雑になり、途中の処理結果がデータストアに残ったまま最初からリトライしてしまうなど、べき等な結果が得られない危険性があります。

例えば、データベースへの書き込みがリトライにより2回行われたとき、同じレコードが重複して2行存在してしまうような結果になると、これはべき等ではありません。

べき等性がない場合のリトライ処理

逆に、以下のような実装がべき等な例であると言えます。

  • データの書き込み前に、データが存在することをチェックし、存在していれば書き込みを行わない
  • データが既に存在していれば上書き、存在しなければ追記 (SQL における UPSERT)

べき等性がある場合のリトライ処理

解説記事リンク

Google における代表的なサーバーレスプロダクトの詳細については、以下のブログ記事で解説しています。

佐々木 駿太 (記事一覧)

G-gen最北端、北海道在住のクラウドソリューション部エンジニア

2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。

趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。