クラウドネイティブ アプリケーション
デザイン パターン詳細
Cloud Run + Cloud Firestore
解決する課題・使い所
クラウドネイティブ アプリケーションの開発と運用に求められる要因にはアジリティと運用効率性があります。変化が早い市場に対してより早くアプリケーションを開発し稼働させること、また継続的にアプリケーションの改善に注力できるように運用効率を上げていくことが重要視されています。
サーバーレス アーキテクチャは、上記要件を満たす事が可能なアプローチとなります。インフラストラクチャの構成および運用をクラウド プラットフォームに委任し、開発者はよりアプリケーション開発に注力することが可能となります。また、ここでは上記のクラウドネイティブ アプリケーションに求められる要件の アジリティと運用効率性に加え、スケーラビリティも考慮してサーバレス コンテナの Cloud Run と サーバレス データベースの Cloud Firestore による構成を紹介します。
使い所
- 単一機能にフォーカスしているアプリケーション
- 複数の業務ドメインに跨ってデータを結合して評価を行うような業務アプリケーションには向いていません。
- データ設計よりも業務ロジック中心的な開発を行うアプリケーション
- アジャイル開発のように作りながら動かし、アウトプットとなるデータを永続化するという開発に向いています。
- スモールスタートしビジネスの成長に伴い徐々にスケールしていくアプリケーション
- Google Cloud の無料枠利用でサーバレスの構成でアプリケーションをスタートしたらインフラの運用管理とランニングコストを両方ゼロに近く抑えることが可能です。そしてビジネスの拡大に伴い、 Cloud Run と Cloud Firestore はそれぞれ自動スケールしてくれるので、中小企業や新事業の立ち上げのためのアプリケーションに非常に向いています。
- 適用例
- EC サイトの中のカタログ機能や購入履歴管理のように特定の単一機能
- ユーザーアカウント管理やユーザーアカウントに紐づくインベントリや設定情報管理のような大量データを扱う機能
- ソーシャルサイトの行動履歴ログのようなリアルタイム処理を行う機能
- IoT のようにトランザクションが予期できず膨大なリクエストが発生しうる機能
- 新規事業のインキュベーションようのアプリケーション開発
- 小売店向けにリアルタイムな在庫と商品の詳細を提供する商品カタログ
- ユーザーの過去の行動と好みに応じてカスタマイズされたエクスペリエンスを提供するユーザー プロフィール
- ある銀行口座から別の口座への送金など、ACID プロパティに基づくトランザクション
アーキテクチャ
基本的な構成は、インターネット上に公開されている Cloud Run の Service から Cloud Firestore へ接続する形式になります。接続にはクライアント ライブラリや Firebase Admin SDKs を用いて接続する方法と、HTTP (REST) または gRPC により直接 Cloud Firestore API を呼び出す方法があります。提供しているクライアント ライブラリは、C#、Go、Java、Node.js、PHP、Python、Ruby の各種言語に対応しています。クライアント ライブラリや SDKs を利用する場合は、トランザクションが失敗する場合のリトライやオフラインの対応などを自動的に実施してくれます。
- クライアント ライブラリを用いた接続
- モバイルもしくは Web アプリを開発する場合のクライアントからのアクセス、セキュリティルール経由で権限コントロールすることが可能です。
- スキーマ情報の確認やバッチを実行する場合には、特権ユーザが必要で、Firebase Admin SDKs を利用します。その場合は IAM 経由で権限コントロールされます。
- クライアント ライブラリの概要
- 直接 Cloud Firestore API を呼び出す接続
- 完全なクライアント ライブラリを実行できない環境(例えば IoT デバイス)や他のサービスと簡単に連携したい場合は Cloud Firestore API を呼び出すことが便利です。
- Firestore REST API の使用
不特定多数からのアクセスを抑止し限定的に公開する場合は、サービスを作成する際に「認証を必要とする」を選択します。これによりサービスが非公開となります。アクセスを許可するユーザーを追加し、Cloud Run Invoker (roles/run.invoker) ロールを付与します。また Google Cloud 外部から呼び出す際に Authorization Bearer ヘッダに有効な ID トークンを付与してアクセスを行います。
同様にして Cloud Pub/Sub などの Google Cloud 上のサービスから Cloud Run を呼び出す構成を行う事ができます。
リージョナル サービスで提供されている Cloud Run と Cloud Firestore をマルチリージョンで構成し可用性を向上させる場合には Serverless NEG と HTTP(S) ロードバランサを組み合わせて使用します。また、Serverless NEG を組み合わせた構成では、Cloud Armor を利用してウェブアプリケーションの保護をする事が可能になります。
Cloud Run のフロントエンドに構成する HTTP(S) Load Balancing は、Serverless NEG の構成後に バックエンドサービス、URL マップ、HTTP プロキシ、フォワーディング ルールを作成して構成を行います。
利点
フロントエンドのアプリケーションプラットフォームに Cloud Run を用い、バックエンドのデータストアに Cloud Firestore を用いる構成をとる事でアプリケーション開発および運用の観点に容易にアジリティや効率性を享受することが可能となります。
Cloud Run 利点
- アジリティ
Cloud Run は作成したコンテナ アプリケーションを秒単位でデプロイしサービス公開する事が可能です。また、CI/CD パイプラインをサポートする Cloud Build と統合され自動化されたビルド・デプロイが可能になります。コンテナの作成も Google Cloud Buildpacks を使用することにより Dockerfile の定義を必要なくコンテナイメージを内部で作成して Cloud Run に公開する事が可能です。- ビルド・デプロイの自動化
- コンテナイメージ作成の省力化
- 効率性
Cloud Run にデプロイしたアプリケーションは自動的に Cloud Logging および Cloud Monitoring と統合され、設定や構成の必要なくログ監視やパフォーマンスモニタリングが可能になります。また、デプロイ対象のアプリケーションの特性に応じたリクエストタイムアウトの設定が可能で最小 1 秒から最大 60 分までの範囲で設定する事が可能になります。これにより IoT に窓口アプリケーションから バッチジョブのような様々なアプリケーションに合わせた設定が行えます。- 組み込みのオブザーバビリティ
- Cloud Logging および Cloud Monitoring との統合
- リクエスト タイムアウト設定
- デフォルト タイムアウト 5 分
- 最大 60 分
- 組み込みのオブザーバビリティ
- スケーラビリティ
Cloud Run では受信したリクエストをすべて処理するために自動的にスケーリングが行われます。リクエストを受け付けていない時にはインスタンス数を 0 までスケールダウンし、リクエストが増加してきた場合には 設定した最大数 (デフォルト 最大数 1000) までスケールアウトします。また、各インスタンスが同時に処理するリクエスト数の設定が可能 (最大同時実行数 80) でリソースを効率的に利用したリクエスト処理が可能です。- オートスケーリング
- コンカレンシー
Cloud Firestore 利点
アプリケーション向けのスケーラビリティが高い NoSQL データベースです。シャーディングとレプリケーションを自動的に処理し、アプリケーションの負荷に合わせて自動的にスケールする、可用性と耐久性を兼ね備えたデータベースを提供します。 Cloud Firestore は Native モードと Datastore モードの 2 つのモードを提供します。両方とも同じ基盤となるルーティング インフラストラクチャを使用します。ゆえに、プロジェクトごとにどちらか一方しか利用することができません。 新しいモバイルアプリに Cloud Firestore のリアルタイム機能を利用したい場合、もしくは Firebase 側の機能も一緒に利用したい場合は Native モードが最適なオプションです。 サーバー側でのみ使用する場合、もしくは大規模で書き込みが発生するようなワークロードの場合は、DataStore モードがより適切なオプションになります。 Cloud Firestore の主な利点は下記になります。
- ACID トランザクション
ACID トランザクション、SQL ライクなクエリ、インデックスなどの多くの機能を備えています。 - 簡単にスケーリング
Cloud Firestore は、Google Cloud の強力なインフラストラクチャを活用するためにゼロから構築された自動スケーリングソリューションであり、アプリの成長に合わせて簡単にスケーリングできます。 - スキーマレスによるデータ構造の柔軟性
Cloud Firestore は効率的なクエリ機能を備えた NoSQLドキュメントデータベースであるため、論理的に意味のある方法でデータを階層構造に保つことができます。 - 真のサーバーレスソリューション
Native モードを利用する場合は、モバイルまたはウェブクライアントから直接 Cloud Firestore と通信して、中間となるアプリサーバーを設定する必要はありません。 - 包括的なクライアントライブラリ
Cloud Firestore は、ネイティブモバイルアプリ用とWeb 用の両方のリッチで包括的なクライアントライブラリによってサポートされており、Cloud Firestore での作業をシンプルで楽しいものにします。特に Native モードのクライアントライブラリには、次のような特徴があります。- オフラインサポート
Cloud Firestore は、ウェブを含む完全なオフラインサポートを備えているため、ユーザーはネットワークに接続していない場合でもデータにアクセスして変更を加えることができます。クライアントライブラリを使用すると、アプリの意味に応じて、データへの変更を自動的に受信したり、必要に応じてデータをプッシュしてリクエストしたりできます。 - 自動同期
Cloud Firestore を使用すると、データが変更されたときにアプリケーションをほぼリアルタイムで更新できます。これは、共同のマルチユーザーアプリケーションを構築するのに最適なだけでなく、複数のデバイスからアプリを使用する可能性のある個々のユーザーとデータを同期させることができることも意味します。 - 使いやすさ
Cloud Firestore の慣用的なクライアントライブラリを使用すると、ネットワーク接続の確立や予期しない競合状態の処理を心配する必要なく、新しいデータを簡単に更新して受信できます。
- オフラインサポート
注意事項
Cloud Run についての注意事項
- 向かないアプリケーションのパターン
- 長時間のトランザクション時間を要するアプリケーション
- バッチプログラムなど
- ただし、タイムアウト時間を最大 60 分に設定するベータ機能を提供しているため、今後バッチ等のアプリケーションも利用可能
- CPU リソースを多く要する演算が中心のアプリケーション
-
- 最大 4 vCPU までの割当て可能ですがそれ以上のリソースが必要な演算処理がある場合は GKE の利用を検討してください
-
- 長時間のトランザクション時間を要するアプリケーション
- コンテナ インスタンスが起動するときにレイテンシが発生します。この時間を最小化した設計を考慮することを推奨します。
- コンテナインスタンスの終了時処理の検討
-
-
-
- Cloud Run では自動でコンテナ数がスケールします。そのためコンテナが終了する時に送信される SIGTERM を利用したアプリケーションによるグレースフルシャットダウンの検討を推奨します。
-
-
-
Cloud Firestoreについての注意事項
- トラフィックを徐々に増やす
- Cloud Firestore では新しい種類 (Datastore モード) もしくはコレクション(Native モード) の操作には毎秒 500 回を上限としています。その後、5 分ごとにトラフィックを 50% 増やしていくことをおすすめします。この方法で読み取りトラフィックを増やした場合、90 分後には毎秒 740,000 回のオペレーションに増やすことができます。
- 狭いキー範囲に対する高頻度の読み取り、書き込み、削除を行わないでください。
- Cloud Firestore に向いていないユースケース
- 複雑な SQL で OLTP 系のワークロードを取り扱うシステムでは、Cloud SQLや Cloud Spanner を検討してください
- オンライン分析処理 (OLAP) システムでのインタラクティブなクエリが必要な場合は、BigQuery を検討してください。
- 大容量の画像やムービーなど、大規模な不変 blob を格納する必要がある場合は、Cloud Storage を検討してください。
- Native モードの制限
- 1 秒あたり 1 のドキュメント書き込み頻度制限
- 典型的なケースとして、あるドキュメントに頻繁に発生するイベントのカウントーが保存されるような設計になったら問題になり易いです。この問題に対応するには、複数のドキュメント間でカウンターを分割する「分散カウンタ」と呼ばれる代替ソリューションの利用を検討してください。
- 1MB のドキュメントサイズ制限 時間と共に、無制限に大きくなる可能性のあるマップおよび配列タイプのフィールドの使用をなるべく避けてください。
- 1秒あたり 10,000 の書き込み
- トランザクションごとに最大 500 のドキュメント処理可能
- 同時接続最大数は 1,000,000 まで
- 1 秒あたり 1 のドキュメント書き込み頻度制限
サンプル コンフィグ
- [Qwiklabs] Google Cloud Run Serverless Workshop
- Cloud Firestore データベースへデータを読み込む
- Cloud Firebase を使用してサーバーレス ウェブアプリをビルドする
- Cloud Run を使用して PDF ファイルを作成するサーバーレス アプリをビルドする
- Cloud Run と Pub/Sub を使用して復元性に優れた非同期システムをビルドする
- [Qwiklabs] Google Cloud サーバーレス プラットフォームへの Go アプリのデプロイ
参照文献
- Google Cloud サービスへの接続
- サーバーレス ネットワーク エンドポイント グループの概要
- サーバーレス NEG の設定
- Cloud Run(フルマネージド)のリソースの上限
- Get to know Cloud Firestore シリーズ
- ネイティブ モードと Datastore モードからの選択
- Firestore のベスト プラクティス
- Cloud Firestore のクエリが遅くなる理由
- The top 10 things to know about Firestore when choosing a database for your app
- Cloud Datastore のベスト プラクティス
- Datastore での高速で信頼性の高いランキング処理
- Datastore での強整合性と結果整合性のバランス