Chương 35: Cloud Pub/Sub — Kiến Trúc & Delivery Semantics
Cloud Pub/Sub là messaging backbone của Google Cloud — mọi thứ từ event streaming, pipeline xử lý dữ liệu, đến fan-out giữa microservice đều đi qua nó. Không giống Kafka hay RabbitMQ, Pub/Sub được thiết kế từ đầu để là serverless, globally-managed, và pay-per-use. Nhưng điều đó không có nghĩa là bạn có thể dùng nó mà không hiểu cơ chế bên trong.
Delivery semantics, ordering guarantees, ack deadline — những khái niệm này không phải tùy chọn để đọc cho vui. Hiểu sai chúng là nguyên nhân trực tiếp của duplicate processing, message loss, và ordering violation trong production.
Tại sao chương này quan trọng
Pub/Sub tự quảng cáo là "simple". Nhưng "simple" ở đây có nghĩa là simple to use, not simple to reason about under failure. Những vấn đề phổ biến nhất trong production:
- Duplicate messages dù subscriber đã ack — vì hiểu sai at-least-once semantics
- Message reordering dù bật ordering keys — vì không hiểu regional scope requirement
- Silent message loss — vì ack deadline expire và không ai hay biết
- Consumer lag không giảm được — vì flow control chặn subscriber mà không có monitoring đúng
- Dead letter topic không trigger — vì nhầm giữa "delivery attempts" và "processing attempts"
Chương này xây dựng mental model đúng từ trong ra ngoài: từ cách Pub/Sub lưu trữ và replicate message, đến cách delivery semantics được enforce, đến các cơ chế kiểm soát luồng dữ liệu.
Cấu trúc chương
chapter-35-cloud-pubsub/
├── index.md # File này
├── 01.architecture-message-lifecycle.md # Kiến trúc distributed log, sharding, message lifecycle
├── 02.delivery-semantics.md # At-least-once vs exactly-once, ack deadline mechanics
├── 03.pull-subscriptions.md # Unary Pull, StreamingPull, connection management
├── 04.push-subscriptions.md # Push endpoint, retry mechanics, push window
├── 05.ordering-keys.md # Per-key ordering, regional scope, throughput limits
├── 06.dead-letter-topics.md # DLT trigger conditions, attributes, DLT subscription
├── 07.flow-control-backpressure.md # Flow control, backpressure, subscriber scaling metrics
└── 08.schemas-consumer-scaling.md # Avro/Protobuf schemas, consumer scaling patternsDanh sách subtopics
1. Kiến Trúc Pub/Sub & Message Lifecycle
Đây là nền tảng của mọi thứ. Giải thích cách Pub/Sub được thiết kế bên trong như một distributed log được sharded theo subscription: cách message được lưu, replicate, và cuối cùng được xóa sau khi mọi subscription đã ack. Phần này xây dựng mental model về "message sống ở đâu và đi đâu".
Nội dung chính:
- Pub/Sub không phải Kafka: message store per-subscription, không per-topic
- Sharding: message được phân phối trên nhiều storage server
- Replication: multi-zone durability, sync write trước khi publish ack
- Message lifecycle: Published → Stored → Delivered → Acked → Deleted
- Tại sao at-least-once là default: lease-based delivery model
2. Delivery Semantics & Ack Deadline
Giải thích sâu hai delivery semantic: at-least-once (default) và exactly-once (opt-in). Đây là phần nhiều người hiểu sai nhất. Cũng giải thích ack deadline — cơ chế core của mọi delivery guarantee — bao gồm extension mechanics và max 600 giây.
Nội dung chính:
- At-least-once: lease-based model, tại sao duplicate xảy ra
- Exactly-once: regional constraint, internal deduplication state, pull-only limitation
- Ack deadline: default 10s–600s, ModifyAckDeadline extension
- Ack deadline expiry: re-delivery behavior, lease recovery
- So sánh latency và throughput tradeoffs
3. Pull Subscriptions — Unary Pull & StreamingPull
Hai API pull hoàn toàn khác nhau về cơ chế. Unary Pull là request-response đơn giản. StreamingPull là persistent bidirectional gRPC stream — đây là cách client library thật sự hoạt động. Hiểu sự khác biệt này giải thích tại sao throughput thay đổi đột ngột khi connection bị reset.
Nội dung chính:
- Unary Pull: request-response model, max 1000 messages/request
- StreamingPull: persistent gRPC stream, server-initiated push
- Connection lifecycle: server-side reset sau timeout dài
- Ack management trong StreamingPull: lease manager
- Khi nào dùng Unary vs StreamingPull
4. Push Subscriptions — HTTP Endpoint & Retry Mechanics
Push subscription đảo ngược mô hình: Pub/Sub chủ động gọi HTTP endpoint của bạn. Hiểu push window, slow-start algorithm, và cơ chế backoff là bắt buộc để tránh overload endpoint khi burst.
Nội dung chính:
- Push delivery model: Pub/Sub như HTTP client
- Push window: slow-start, 3000 outstanding messages per region cap
- Retry mechanics: exponential backoff 100ms–60s
- Authentication: JWT signing
- Ordering với push: single outstanding message per ordering key
5. Ordering Keys — Per-Key Guarantee & Regional Scope
Ordering keys là một trong những tính năng bị hiểu sai nhiều nhất. Guarantee chỉ là per-key, within-region — không phải global. File này giải thích cơ chế bên trong, tại sao chỉ dùng được single-region endpoint, và hot key problem.
Nội dung chính:
- Ordering key mechanics: "only one batch outstanding per key"
- Regional scope: tại sao phải publish qua single-region endpoint
- Throughput limit: 1 MBps per ordering key
- Hot key problem: ordering key trở thành bottleneck
- Interplay giữa ordering và exactly-once delivery
6. Dead Letter Topics — Trigger & Processing
Dead Letter Topic là cơ chế quan trọng để xử lý message không xử lý được. Nhưng "max delivery attempts" là approximate, không exact. File này giải thích khi nào DLT trigger, payload structure, và cách xử lý dead letters đúng cách.
Nội dung chính:
- Trigger condition: max delivery attempts (5–100, approximate)
- DLT mechanics: message được wrap lại với metadata attributes
- DLT subscription: tách biệt với source subscription
- IAM requirements: Pub/Sub service account cần quyền publish vào DLT topic
- Monitoring dead letter rate
7. Flow Control & Backpressure
Flow control là cơ chế subscriber tự bảo vệ khỏi bị overwhelm. maxOutstandingMessages và maxOutstandingBytes là hai tham số chính. File này giải thích cơ chế dual-watermark, tại sao flow control không giải quyết được persistent overload, và metrics để scale subscriber.
Nội dung chính:
- Dual-watermark flow control: message count + byte size
- Khi flow control trigger: subscriber pause, backlog tăng
- Metrics quan trọng:
subscription/num_undelivered_messages,subscription/oldest_unacked_message_age - Scaling subscriber: dựa vào backlog metrics
- Flow control không phải load balancer: hiểu đúng vai trò
8. Schemas & Consumer Scaling Patterns
Message schema (Avro/Protobuf) là cơ chế enforce contract giữa publisher và subscriber. Consumer scaling pattern là cách thiết kế subscriber fleet đúng cho các use case khác nhau.
Nội dung chính:
- Schema types: Avro 1.11 vs Protocol Buffers proto2/proto3
- Schema enforcement: reject trước khi store
- Schema evolution: revision model, 20 revisions per schema
- Consumer scaling: fan-out subscriptions, competing consumers pattern
- Pull subscriber parallelism: nhiều process cùng một subscription
Điều kiện tiên quyết
- Distributed systems fundamentals: Eventual consistency, idempotency, at-least-once vs exactly-once semantics
- Messaging patterns: Topic-based publish-subscribe, queue semantics
- gRPC basics: Streaming RPC concepts (cho phần StreamingPull)
- Chương 9: KEDA Pub/Sub scaler dùng metrics từ chương này
Quan hệ với các chương khác
Pub/Sub là messaging backbone — kết nối với nhiều chương:
Producer side:
Cloud Functions / Cloud Run → publish events → [Pub/Sub]
GKE workloads → publish events → [Pub/Sub]
Consumer side:
[Pub/Sub] → trigger → Cloud Functions (Chương 36)
[Pub/Sub] → KEDA scaler → GKE workload scale (Chương 9)
[Pub/Sub] → Dataflow pipeline → BigQuery (Chương 38)
Security:
IAM cho topic/subscription → Chương 31
VPC-SC perimeter → Chương 33Tham khảo nhanh
| Khái niệm | Mô tả |
|---|---|
| Topic | Kênh nhận message từ publisher |
| Subscription | Kênh deliver message tới subscriber |
| Ack deadline | Thời gian subscriber phải ack trước khi message bị redeliver |
| Ordering key | String identifier gán cho message để đảm bảo thứ tự per-key |
| Dead Letter Topic | Topic nhận message không ack được sau N lần delivery |
| StreamingPull | gRPC bidirectional stream để receive messages |
| Flow control | Cơ chế subscriber giới hạn tốc độ nhận message |
| Exactly-once | Delivery semantic đảm bảo không duplicate, chỉ cho pull, within-region |