訊息系統有兩種基本投遞模型:point-to-point(一則訊息只給一個消費者)與 publish-subscribe(一則訊息可給多個訂閱者)。分散式訊息佇列用 topic / partition / consumer group 這組原語把兩者統一表達,並讓吞吐可水平擴展。
🧠 Core Ideas
TIP
Topic 是訊息的分類;topic 切成多個 partition 分散到不同 broker(可水平擴展)。每個 partition 是一條 FIFO、訊息位置叫 offset。相同 message key 的訊息進同一 partition(保序)。Consumer group 各自維護消費 offset——group 間是 pub/sub(扇出),把所有 consumer 塞進同一 group 就退化成 point-to-point。
- Point-to-point:訊息只被一個 consumer 消費、確認後移除,通常不保存。
- Publish-subscribe:訊息送到 topic,被所有訂閱的 group 各自收到。
- 關鍵限制:同一 group 內,一個 partition 只給一個 consumer——所以 group 內 consumer 數 > partition 數時,多的那些收不到資料。要更高平行度就加 partition。
⚖️ Push vs Pull
大多數訊息佇列選 pull
- Push:broker 一收到就推,延遲低;但消費慢時 consumer 會被淹沒,broker 得控速。
- Pull:consumer 自己控速、可分即時/批次兩組、消費慢可自行追上、更適合 batching。缺點是沒訊息時空拉浪費資源 → 用 long polling(拉取時等一段時間等新訊息)解。
Consumer rebalancing
- consumer 加入/離開/崩潰、或 partition 調整時,要重新分配「誰負責哪些 partition」。
- Coordinator(某個 broker)收 heartbeat、管 offset;consumer 清單變化時選出 group leader,leader 產生 partition 分派計畫,coordinator 廣播。
- 崩潰=coordinator 在時限內收不到 heartbeat → 標記死亡 → 觸發 rebalance。
⚖️ 資料傳遞語意(At-most / At-least / Exactly-once)
三種語意:定義與代價
- At-most once:可能遺失、不重送。producer ack=0 不重試;consumer 處理前先提交 offset。適合可容忍遺失的 metric。
- At-least once:不遺失、可能重複。producer 重試至成功;consumer 處理成功後才提交 offset。適合能在 consumer 端去重(冪等)的場景。
- Exactly-once:最難、對效能與複雜度代價高。適合金融(支付/交易/會計),尤其重複不可接受、下游又不支援冪等時。
複製與 ACK(耐久性 vs 延遲)
- 每個 partition 有多複本;leader 收寫、follower 拉取。ISR (in-sync replicas) 是與 leader 同步的複本集。
- ACK=all(等所有 ISR,最耐久最慢)/ACK=1(leader 落盤即回,leader 在複製前掛會丟)/ACK=0(不等,最低延遲、可能丟,適合 log/metric)。
- 底層儲存偏好 WAL(append-only log)+segment:純循序讀寫,充分利用磁碟循序效能與 OS 快取。
WARNING
減少 partition 比增加複雜得多——被除役的 partition 不能立刻刪(可能還在被消費),要等保存期過才截斷。別把「減 partition」當回收空間的捷徑。
🔑 Takeaways
- pub/sub 與 point-to-point 用 topic / partition / consumer group 統一表達;靠加 partition 擴展吞吐。
- 同 group 內 partition : consumer = 1 : 1——這是平行度上限。
- 傳遞語意是遺失 vs 重複 vs 成本的取捨;能去重就選 at-least-once + 冪等。
- ACK 等級是耐久性換延遲的旋鈕;底層用 WAL 吃循序磁碟效能。
No notes yet — jot your takeaways or Q&A here.