GCP: Cloud Pub/Sub

# Overview

https://cloud.google.com/pubsub/docs/overview

- 非同期メッセージングサービス
- メッセージングミドルウェアやストリーミング分析パイプラインとして使える
- Pub/Sub Lite: より安価なモード、低信頼性、ゾーナルかリージョナル、キャパシティを指定する
- トピック: パブリッシャからメッセージが送られるリソース
- サブスクリプション: 特定のトピックからアプリケーションにメッセージを送るリソース
- メッセージ: データとアトリビュートの組み合わせ
- メッセージアトリビュート: パブリッシャが定義するキーバリューペア
- アクノリッジメント: サブスクライバから送られる受信成功の通知

## fan-in / fan-out

![fan](https://cloud.google.com/static/pubsub/images/many-to-many.svg)

## メッセージのフロー

![flow](https://cloud.google.com/static/pubsub/images/pub_sub_flow.svg)

# Architectural overview

https://cloud.google.com/pubsub/architecture

- GCPの全てのリージョンで動く
- 複数のリージョンのパブリッシャが一つのトピックに書き込める
- あるトピックのメッセージは複数のリージョンに保存される場合がある
- サブスクライバは最も近いサーバーからデータを取得する
- データプレーン: メッセージをパブリッシャとサブスクライバの間で動かす, フォワーダ
- コントロールプレーン: パブリッシャとサブスクライバをサーバーに割り当てる, ルータ

![forwarder_image](https://cloud.google.com/static/pubsub/images/wp_msg_lifecycle.svg)

# Pub/Sub Liteとの比較

https://cloud.google.com/pubsub/docs/choosing-pubsub-or-lite

- コストが優先されるときはLite
- 運用の負荷が増える
- 可用性も下がる
- レプリケーションが非同期になる

# Cloud Tasksとの比較

https://cloud.google.com/pubsub/docs/choosing-pubsub-or-cloud-tasks

- Pub/Sub
    - パブリッシャとサブスクライバの分離
    - メッセージが配信されることを保証しない
    - メッセージの保持は7日まで
    - グローバル
    - 暗黙の呼び出し
- Tasks
    - 明示的な呼び出し
    - パブリッシャが実行を制御する
    - パブリッシャがどこに配信するかを管理する
    - プロデューサー側が管理するときに有用
    - メッセージの保持は30日まで
    - リージョナル

# Create a topic

https://cloud.google.com/pubsub/docs/admin

- デフォルトサブスクリプションを設定する
    - ID
    - プルタイプ
    - メッセージ保持時間
    - inactivityによる揮発
    - 10秒のacknowledgement期限
    - リトライポリシー
- スキーマ: データフィールドのフォーマット
- CMEKを使うかどうか

# Creating schemas

https://cloud.google.com/pubsub/docs/schemas

AvroかProtocol Bufferに基づく

# Publish messages

https://cloud.google.com/pubsub/docs/publisher

- メッセージ: 以下を指定する
    - メッセージデータ
    - オーダリングキー: メッセージのソートを可能にする
    - アトリビュート
- Pub/Subが以下を追加する
    - トピックでユニークなID
    - Pub/Subがメッセージを受信したタイムスタンプ
- 複数のメッセージを送信するバッチ化が可能
    - スループットが上がる
    - レイテンシが下がる
- gRPC + Gzipで圧縮できる
- デフォルトでリトライするが、一部エラーではリトライしない
    - リトライを設定できる
    - 待ち時間の指数的バックオフなど
    - オーダリングキーがあるとき、設定を無視してリトライする
- `DEADLINE_EXCEEDED` エラーはおおむね送信キャパシティを超えているとき

# Subscription type

https://cloud.google.com/pubsub/docs/subscriber

- サブスクライバはトピックにacknowledgeを送る
    - 送る時間が `ackDeadline` を超えると送信に失敗したとみなされ、再配信される
## Pull

- サブスクライバがプルリクエストを送る
- メッセージが多いとき
- 効率性やスループットが必要な時
- パブリックのHTTPSが使えないとき
- サブスクリプションを増やすことでロードバランス
- デリバリタイムを下げたいときは効率的ではない

![pull_image](https://cloud.google.com/static/pubsub/images/subscriber_pull.png)

詳細

https://cloud.google.com/pubsub/docs/pull

## Push

- Pub/Subサービスがサブスクライバにプッシュする
- 複数のトピックを同じウェブフックで使いたいとき
- App EngineやCloud Functions
- Google Cloud環境が適していないとき
- パブリックHTTPSエンドポイント
- プッシュ先エンドポイントがロードバランス
- SSL認証が必須

![push_image](https://cloud.google.com/static/pubsub/images/subscriber_push.png)

詳細

https://cloud.google.com/pubsub/docs/push

## BigQuery

- BigQueryテーブルに書き込む
- メッセージボリュームが大きいとき
- 直接BigQueryに書き込みたいとき
- Pub/Subがロードバランス

![bigquery_image](https://cloud.google.com/static/pubsub/images/subscriber_bigquery.png)

詳細

https://cloud.google.com/pubsub/docs/bigquery

# Audit, Security

https://cloud.google.com/pubsub/docs/audit-logging

https://cloud.google.com/pubsub/docs/monitoring

- Audit log
- in-transit / at-rest で暗号化
- メッセージストレージポリシーでリージョンを限定できる
- Cloud Monitoring