【PCD】WEB問題集:クラウドネイティブアプリの設計編

WEB問題集

PCD#1(designing)

あなたのチームはステートレスな REST API を構築しており、HTTPS、カスタムドメイン、リクエスト単位課金で、ゼロから毎秒数千リクエストまで自動スケールさせたいと考えています。コードはコンテナイメージとして配信されます。どの Google Cloud サービスを採用すべきですか。

ディスカッション 0

正解:B

【正解: B】の理由

ステートレスな REST API をコンテナイメージのまま動かし、ゼロから毎秒数千リクエストまで自動で追随させたいという要件に Cloud Run が過不足なく合致します。Cloud Run はコンテナイメージをビルドできる言語であればそのままデプロイでき、受信リクエスト数に応じてインスタンスを水平に増減させます。リクエストが途切れれば最後の 1 インスタンスも削除されるゼロスケールが既定動作のため、待機分の費用が発生しません。各サービスには run.app のサブドメイン上に HTTPS エンドポイントが自動付与され、カスタムドメインも割り当てられます。課金はリクエスト単位の料金に加えて、割り当てた CPU とメモリを 100 ミリ秒粒度で計上する従量制です。

【サービス比較】

サービス配信単位ゼロスケール課金の粒度
Cloud Runコンテナイメージ既定で対応リクエストと秒課金
App Engine Standard言語ランタイム対応インスタンス時間
Compute Engine MIG仮想マシン不可VM 稼働時間
Cloud Run functions 第 1 世代関数ソース対応呼び出しと実行時間

【他の選択肢が不適切な理由】

  • A: App Engine スタンダード環境はサポート言語のランタイムを使うサンドボックス内でインスタンスを実行する方式で、任意のコンテナイメージをそのまま配信する要件を満たしません。
  • C: マネージド インスタンス グループと HTTPS ロードバランサは仮想マシン単位の課金で、常時稼働とウォームアップが前提となるためリクエスト単位課金の条件から外れます。
  • D: 第 1 世代の Cloud Run functions は関数のソース単位でデプロイする実行環境で、任意のコンテナイメージを持ち込んで動かす配信形態には対応しません。

【参考】

Cloud Run とは / App Engine の環境

PCD#2(designing)

プロデューサーサービスからイベントを発行し、複数のコンシューマーへファンアウト配信したいと考えています。要件は at-least-once 配信、キー単位の順序保証、再試行とデッドレターキューのマネージド管理です。どのサービスを選ぶべきですか。

ディスカッション 0

正解:A

【正解: A】の理由

1 つのトピックに複数のサブスクリプションを作れば、発行された 1 件のイベントがそれぞれの購読者へ複製されて届くため、Pub/Sub だけでファンアウト配信が成立します。配信保証は at-least-once で、確認応答が返らないメッセージは再配信されます。順序キーを付けて発行すると、同じキーを持つメッセージは発行された順に届き、サブスクリプション側で順序指定を有効にすることで受信側にも順序が保たれます。確認応答できないメッセージは配信試行の上限を超えた時点でデッドレター トピックへ転送され、再試行ポリシーとあわせてマネージドに扱えます。

【サービス比較】

要件Pub/Sub での実現方法
ファンアウト1 トピックに複数サブスクリプション
配信保証at-least-once (再配信あり)
キー単位の順序順序キー + サブスクリプションで順序指定を有効化
未達メッセージデッドレター トピック (既定の試行上限 5 回)
サービス本来の役割要件 (ファンアウト・順序・DLQ) への適合
Pub/Subトピックへ発行しサブスクリプションへ配信する3 つの要件をいずれも満たす
Cloud Tasks個々のタスクを 1 つの宛先ワーカーへ引き渡す同一イベントを複数の購読者へ複製できない
Cloud Scheduler指定した時刻にジョブを起動するイベントの保持と購読者への配信を行わない
Firestore のドキュメント トリガーデータベースへの書き込みを起点に通知する任意の発行者からのイベントを扱えない

【他の選択肢が不適切な理由】

  • B: Cloud Tasks は個々のタスクを 1 つの宛先ワーカーへ引き渡すキューで、同じイベントを複数の購読者へ同時に届けるファンアウト構成には向きません。
  • C: Cloud Scheduler は指定した時刻にジョブを起動するスケジューラであり、イベントを保持して購読者へ配信する経路や順序保証の仕組みを持ちません。
  • D: Firestore のドキュメント トリガーはデータベースの書き込みを起点とする通知で、任意の発行者からのイベントを扱う汎用の配信基盤にはなりません。

【参考】

メッセージの順序指定 / デッドレター トピック

PCD#3(designing)

モバイルアプリのユーザープロファイルドキュメントを格納する必要があります。要件は低レイテンシ読取、モバイルクライアントへのリアルタイム同期、オフラインキャッシュ対応です。最も適したデータベースはどれですか。

ディスカッション 0

正解:C

【正解: C】の理由

モバイル クライアントとの同期が中心となる要件では、Firestore の Native モードが最も適合します。モバイルとウェブの SDK はドキュメントやクエリに対してリスナーを登録でき、初回にスナップショットを受け取ったあとサーバー側の変更が起きるたびに差分が push されます。ローカル書き込みは遅延補償によって即座にリスナーへ反映されます。さらにオフライン キャッシュを使うと、端末が接続を失っている間でもキャッシュ済みデータの読み取り、書き込み、クエリを継続でき、復帰時に同期されます。ドキュメント指向のため、項目が利用者ごとに異なるプロファイルの保持にも向きます。

【サービス比較】

要件Firestore Native モードの機能
リアルタイム同期スナップショット リスナーで変更を push
オフライン対応ローカル キャッシュ (Android と Apple は既定で有効、ウェブは明示的に有効化)
データモデルスキーマ柔軟なドキュメント
選択肢端末の SDK から直接読み書き変更のリアルタイム受信オフライン キャッシュ
Firestore (Native モード)できるスナップショット リスナー端末側で保持できる
Cloud SQL for PostgreSQLサーバー経由が前提仕組みが無い無い
Spanner (マルチリージョン)サーバー経由が前提端末向けの API は無い無い
Bigtable (HDD)サーバー経由が前提端末向けの API は無い無い

【他の選択肢が不適切な理由】

  • A: Cloud SQL はサーバー側から使うリレーショナル エンジンで、モバイル端末が直接つなぐ SDK も変更通知を受け取る仕組みも備えていません。
  • B: Spanner は広域でも強整合を保つトランザクション処理が強みですが、端末側のオフライン キャッシュや変更リスナーの API は提供していません。
  • D: Bigtable は大量の時系列やワイドカラム データ向けの NoSQL で、クライアント端末と直接同期するモバイル SDK を持ちません。

【参考】

リアルタイム更新の取得 / オフライン データの有効化

PCD#4(designing)

Cloud Run で稼働するアプリケーションが、Cloud SQL データベースへインターネットを介さずプライベートにアクセスする必要があります。どの構成を採用すべきですか。

ディスカッション 0

正解:C

【正解: C】の理由

公衆インターネットを経由せずに接続するには、経路そのものを VPC の内部アドレス空間に閉じる必要があります。Cloud Run の Direct VPC egress を構成すると、指定したサブネットから内部 IP アドレスが割り当てられ、コネクタを追加しなくても VPC 内のリソースへ直接送出できます。接続先の Cloud SQL インスタンスをプライベート IP で構成しておけば、通信は Google のネットワーク内で完結します。さらに Cloud SQL Auth Proxy やコネクタ ライブラリを併用すると、経路の暗号化と IAM に基づく認可が加わり、パスワードだけに依存しない接続にできます。

【サービス比較】

構成要素役割
Direct VPC egressサブネットの内部 IP で VPC へ直接送出する
Cloud SQL のプライベート IPインスタンスに VPC 内アドレスだけを持たせる
Cloud SQL Auth Proxy とコネクタ暗号化と IAM ベースの認可を付与する
Cloud NAT外向き通信に公開 IP を割り当てる。宛先へは公衆インターネット経由で到達する
パブリック IP と承認済みネットワーク送信元アドレスを絞るだけで、通信自体はパブリック IP を経由する
Cloud VPNVPC と外部拠点を結ぶトンネル。サーバーレスで動く Cloud Run は終端にできない

【他の選択肢が不適切な理由】

  • A: Cloud NAT は外向き通信に公開 IP を割り当てる仕組みで、宛先へは公衆インターネット経由で到達するためプライベート接続という前提と逆になります。
  • B: 承認済みネットワークで送信元アドレスを絞り込んでも、通信自体はパブリック IP を経由するので、インターネットを介さないという条件を満たしません。
  • D: Cloud VPN は VPC と外部拠点を結ぶトンネルであり、サーバーレスで実行される Cloud Run をトンネルの終端として構成することはできません。

【参考】

Cloud Run から Cloud SQL に接続する / Direct VPC egress

PCD#5(designing)

GKE 上のマイクロサービスを Blue/Green 戦略でデプロイし、エラー率が 1% を超えた場合に自動でロールバックさせたい場合、ベストプラクティスに合致する設計の組み合わせを 2 つ選んでください。

(2つ選択)

ディスカッション 0

正解:A, B

【正解: AB】の理由

要件は、段階的にリリースを切り替える仕組みと、切り替えの可否を判断するシグナルの 2 つに分かれます。前者は Cloud Build でイメージをビルドし、Cloud Deploy にデリバリー パイプラインを定義する構成が該当します。Cloud Deploy はレンダリングとデプロイに Skaffold を用い、マニフェストを対象環境ごとに描画してから適用し、すべてのデプロイ戦略でロールバックに対応します。後者は Cloud Monitoring のアラート ポリシーが担い、エラー率のしきい値条件が満たされるとインシデントが作成され通知チャネルへ送られるため、これを契機に旧リビジョンへ戻す運用を自動化できます。

【サービス比較】

役割担当するサービス
ビルドと成果物生成Cloud Build
マニフェストの描画と適用Cloud Deploy と Skaffold
リリースの昇格とロールバックCloud Deploy のパイプライン
エラー率の検出と通知Cloud Monitoring のアラート ポリシー
単発処理の起動のみで昇格や差し戻しは扱えないCloud Source Repositories と Cloud Run functions トリガー
バッチの依存関係の実行でリリース管理は担えないCloud Composer DAG と kubectl operator

【他の選択肢が不適切な理由】

  • C: リポジトリと関数トリガーの組み合わせは単発の処理を起動できるだけで、環境ごとの昇格や失敗時のロールバックを含むリリース管理を統制できません。
  • D: Cloud Composer はバッチ処理の依存関係を並べるワークフロー基盤で、リリースの段階的な切り替えと差し戻しを扱うデリバリー基盤としては設計されていません。

【参考】

Cloud Deploy と Skaffold / アラート ポリシーの仕組み