Cloud Service
Pub/Sub
フルマネージドの非同期メッセージング基盤。トピックへ発行したメッセージを多数のサブスクライバーへ届け、キュー(SQS 相当)とファンアウト(SNS 相当)の両方をこなす。
- 1.トピックへ発行し購読側へ届けるフルマネージドな非同期基盤。
- 2.送信と処理を疎結合化しスパイクを吸収、同報配信も1本でこなす。
- 3.配信は最低1回でまれに重複するため処理は冪等に作るのが鉄則。
解決する課題
物理的なメッセージブローカーの構築・運用やスケール調整を待たずに、グローバルに分散したメッセージ配信をすぐ使えます。
- アクセス急増でバックエンドが詰まる → サブスクリプションがバッファして処理側のペースで捌く
- 送信側と処理側を 疎結合 にして独立にスケールしたい
- 1 件のイベントを 複数の処理系へ同報(ファンアウト) したい(在庫更新・通知・分析へ同時配信など)
- 失敗したメッセージを 安全に退避・再試行 したい(デッドレタートピック)
- リージョンをまたいでも 同一エンドポイント で発行・購読したい(グローバルサービス)
主要概念と用語
- トピック(Topic): メッセージの発行先。AWS の SNS トピックに相当
- サブスクリプション(Subscription): トピックに紐づくメッセージの受け取り口。1 トピックに複数のサブスクリプションを付けるとファンアウトになり、各サブスクリプションが独立したコピーを受け取る
- パブリッシャー / サブスクライバー: 発行側 / 購読側のクライアント
- Pull サブスクリプション: サブスクライバーが API でメッセージを取得し、
ack(確認応答)で削除。AWS SQS のポーリングに近い - Push サブスクリプション: Pub/Sub が HTTPS エンドポイント(Cloud Run / Cloud Functions / 任意の URL)へメッセージを POST する
- 確認応答(ack)と ackDeadline: 取得したメッセージを処理し終えたら
ack。ackDeadline(既定 10 秒、最大 600 秒)までにackしないと 再配信 される(SQS の可視性タイムアウト相当) - メッセージ保持(retention):
ack前のメッセージの保持期間。サブスクリプション既定 7 日(最大 7 日)。トピック側でも保持を有効化でき、シーク(Seek) で過去へ巻き戻して再処理できる - 順序指定キー(ordering key): 同一キーのメッセージを 発行順 に届ける(FIFO 的な順序保証)
- デッドレタートピック(Dead-letter topic): 規定回数(
maxDeliveryAttempts)失敗したメッセージの退避先トピック - スキーマ(Schema): Avro / Protocol Buffers でメッセージ構造を検証
- Pub/Sub Lite: 低コスト・ゾーン単位の派生サービス(スループットを事前プロビジョニング)。※2024 年に新規提供は終了予定がアナウンスされており、新規は通常の Pub/Sub を推奨
仕様・制限・クォータ
- 少なくとも 1 回(at-least-once)配信 が基本。まれに重複 するため処理は 冪等 に作る
- メッセージ本文は 最大 10 MB(SQS の 256KB より大きい)
ack前メッセージの保持は 最大 7 日(既定 7 日)。トピック保持を使えばシークで再処理可能ackDeadlineは 10〜600 秒。modifyAckDeadlineで延長(リース延長)できる- グローバルサービス: トピック/サブスクリプションは単一のグローバルなエンドポイントを持ち、配信はメッセージストレージポリシーに従う
- 1 トピックに対して 多数のサブスクリプション(既定上限はあるが大規模利用可)を作成しファンアウトできる
- exactly-once 配信 はオプションで有効化可能(リージョン内・Pull で、
ackの重複排除を保証)
内部の仕組み
パブリッシャーがトピックへ発行すると、メッセージは Pub/Sub の 分散ストレージへ複数コピーで永続化 され、その時点で各サブスクリプションのキューへ振り分けられます。サブスクライバーは Pull なら API で取得、Push なら Pub/Sub からの POST を受信します。取得したメッセージは ackDeadline の間 “処理中” として保持 され、その間は再配信されません。
- 処理に成功して
ackすると、そのサブスクリプションからメッセージが削除される ackDeadline内にackできなければ 再配信(=少なくとも 1 回配信。冪等処理が前提)- 規定回数(
maxDeliveryAttempts)失敗すると デッドレタートピック へ移動する - 順序指定キー を付けると、同一キーのメッセージは前のメッセージが
ackされるまで次を送らず、発行順を保つ
Pub/Sub は基本「少なくとも 1 回」配信なので まれに重複 します。処理は 冪等 に作るのが鉄則。 厳密な重複排除が要るなら exactly-once 配信 を有効化、順序 が要るなら 順序指定キー を使います。
設計パターン / ベストプラクティス
- ファンアウト: 1 トピックに複数サブスクリプションを付け、通知・分析・在庫更新などへ同報(AWS の SNS → 複数 SQS のパターンを 1 サービスで実現)
- Push → Cloud Run / Cloud Functions: メッセージ到着でサーバーレスを起動。受信側が 2xx を返すと
ack扱い - デッドレタートピック で失敗を退避し、原因調査・再投入。再配信回数は
maxDeliveryAttemptsで制御 - 指数バックオフの再試行ポリシー を設定し、ダウンストリーム障害時のリトライ嵐を抑制
- Pub/Sub → BigQuery サブスクリプション / Cloud Storage サブスクリプション: サブスクライバーのコードを書かずに、メッセージを直接 BigQuery テーブルや GCS に取り込む
- 大きいペイロードや厳密な順序が要る場合は 順序指定キー や スキーマ検証 を併用
- ストリーミング集計が必要なら Dataflow(Apache Beam) と組み合わせる
運用・監視
- Cloud Monitoring のメトリクスで滞留を監視:
subscription/num_undelivered_messages(未配信メッセージ数。SQS のApproximateNumberOfMessagesVisible相当)subscription/oldest_unacked_message_age(最古の未 ack メッセージの経過秒。SQS のApproximateAgeOfOldestMessage相当)
- 滞留増 → サブスクライバー不足や ダウンストリーム障害、
ack失敗を疑う - デッドレタートピックに溜まる → 処理ロジック / 権限(IAM)/ メッセージ形式 を確認
- シーク(Seek) でタイムスタンプ/スナップショットに巻き戻し、再処理やバグ修正後のリプレイが可能
- Push の 4xx/5xx は再配信されるため、受信側エンドポイントの可用性とレイテンシを監視
コスト
課金はおもに メッセージのスループット量(取り込み・配信・保持のデータ量) に対して発生します。リクエスト単位ではなく転送バイト量が中心で、最小課金メッセージサイズの考え方があります。
| コスト要素 | 課金の考え方 | 節約のポイント |
|---|---|---|
| メッセージ取り込み/配信 | 転送データ量(GiB)で課金 | 不要なファンアウト先サブスクリプションを減らす |
| ファンアウト | サブスクリプションごとに配信量が加算 | 本当に必要な購読者だけ接続する |
| メッセージ保持(トピック/シーク用) | 保持データ量×期間で課金 | 必要な保持期間に絞る |
| BigQuery/GCS サブスクリプション | Pub/Sub 配信料+取り込み先の料金 | 中継 ETL を省き運用コストも削減 |
| リージョン間配信 | メッセージストレージポリシーに応じた料金 | ポリシーで配信リージョンを限定 |
セキュリティ
- IAM でトピック/サブスクリプション単位の権限を制御(
roles/pubsub.publisher、roles/pubsub.subscriberなど)。最小権限を徹底 - パブリッシャー/サブスクライバーには サービスアカウント を使い、鍵のハードコードを避ける(AWS の IAM ロール相当)
- 転送中は TLS、保存時は Google 管理鍵で既定暗号化。要件次第で CMEK(Cloud KMS の顧客管理鍵) を指定
- VPC Service Controls で境界を作り、データの持ち出しを防止
- Push サブスクリプションは OIDC トークン認証 を有効化し、エンドポイント側で発行元(サービスアカウント)を検証する
Push エンドポイントを 認証なしの公開 URL で受けるのは NG。誰でも偽メッセージを POST できてしまいます。
OIDC トークン認証 を有効化し、受信側で Authorization ヘッダのトークン(発行元サービスアカウント)を検証してください。
関連サービス・比較(AWS との対応)
| 観点 | Pub/Sub | Amazon SQS | Amazon SNS |
|---|---|---|---|
| モデル | Pub/Sub(1対多)+キュー両対応 | キュー(1対1) | Pub/Sub(1対多) |
| 配信方式 | Pull / Push の両方 | Pull(ポーリング) | Push |
| メッセージ最大 | 10 MB | 256 KB | 256 KB |
| 再配信制御 | ackDeadline(10〜600秒) | 可視性タイムアウト | —(配信のみ) |
| 失敗退避 | デッドレタートピック | デッドレターキュー(DLQ) | —(多くは SQS 側で) |
| 順序/重複排除 | 順序指定キー / exactly-once(任意) | FIFO キュー | FIFO トピック |
| 再処理 | シーク(時刻/スナップショット) | — | — |
| スコープ | グローバル | リージョン | リージョン |
Pub/Sub 1 つで「SQS のキュー(バッファ/疎結合)」と「SNS のファンアウト(同報)」の両方をこなします。 キュー的に使いたいだけなら Pull サブスクリプション 1 本、同報したいなら 複数サブスクリプション を生やすイメージです。
ハンズオン / CLI例
# トピックを作成
gcloud pubsub topics create jobs
# Pull サブスクリプションを作成(ack 期限 30 秒、デッドレターも設定)
gcloud pubsub subscriptions create jobs-sub \
--topic=jobs \
--ack-deadline=30 \
--dead-letter-topic=jobs-dlq \
--max-delivery-attempts=5
# メッセージを発行(属性付き)
gcloud pubsub topics publish jobs \
--message='{"id":"job-1"}' \
--attribute=source=cli
# メッセージを取得して即 ack(手動確認)
gcloud pubsub subscriptions pull jobs-sub --auto-ack --limit=10
# ファンアウト: 同じ jobs トピックにもう 1 本サブスクリプションを追加
gcloud pubsub subscriptions create jobs-analytics --topic=jobs
# Push サブスクリプション(Cloud Run などへ OIDC 認証付きで配信)
gcloud pubsub subscriptions create jobs-push \
--topic=jobs \
--push-endpoint=https://example-xxxx.a.run.app/ \
--push-auth-service-account=pubsub-pusher@PROJECT_ID.iam.gserviceaccount.com
Google Cloud Service
Pub/Subを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
アプリ統合
比較で見る軸
クラウド: Google Cloud / カテゴリ: アプリ統合 / 難易度: intermediate
導入後に効く点
送信と処理を疎結合化しスパイクを吸収、同報配信も1本でこなす。
先に潰すリスク
サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。
- クラウド
- Google Cloud
- カテゴリ
- アプリ統合
- 難易度
- intermediate
- 関連資格
- —
- 設計柱
- reliability / performance / operational / cost
判断チェックリスト
- 自社の用途が「アプリ統合 / reliability」に近いか確認する。
- 強みである「トピックへ発行し購読側へ届けるフルマネージドな非同期基盤。」が本当に評価軸になるか確認する。
- 注意点の「サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。
他クラウドの同等サービス
役割が近いサービスです。設計の置き換えや比較検討の参考に。