iT邦幫忙

2021 iThome 鐵人賽

DAY 29
1
AI & Data

資料工程師修煉之路 Part II系列 第 29

Stream Processing (1-2) - Acknowledgments & Partitioned Logs

Day 28

Acknowledgments and redelivery

老樣子,消費者任何時間都有可能故障,有可能發生 訊息代理 (message broker) 傳遞訊息給消費者後,它卻沒有處理或只處理到一半,為了確保訊息不遺失,broker 使用 acknowledgments:當消費者在處理完訊息後,必須明確的通知 broker,如此 broker 就可以將訊息從 queue 中刪除。

消費者因故障消失時,broker 會將未 acknowledgments 的訊息傳遞給其他消費者,此時若你的傳遞策略是 load balance 時,會發生如下圖 11-2 的影響:訊息 m3 和 m4 傳遞的順序跟事件發生順序不同。

Consumer 2 在處理 m3 到一半時故障,同時 Consumer 1 正在處理 m4, 非 ack 的訊息 m3 會再傳遞給 Consumer 1,其消費訊息的順序為 m4, m3, m5,與發生順序不同。

如果訊息彼此間有因果關係,避免此問題的方法就是為每個消費者使用單獨的 queue(例如不要用 load balance 傳遞策略。)

Partitioned Logs

如果你是使用 AMQP/JMS 風格的訊息模型,當訊息被 acknowledgments 後會從 broker 中刪除,因為它們是以訊息傳遞的思維來建構,如果你在此系統中註冊新增一個消費者,它無法接收註冊前的訊息,相較於資料庫或檔案系統來說就沒這問題,因此,一個混合有耐用性儲存及低延遲訊息通知系統就誕生了:基於 log 的訊息代理 (log-based message broker)

使用 log 儲存訊息

我們在之前討論過 Log-structured 儲存引擎 (2020 Day 8) 和 數據複製 (2020 Day 21),我們可以用相同的架構實作訊息代理:生產者的訊息會附加在 log 中,消費者透過讀取 log 來接收訊息,當消費者讀完訊息了,就後待新訊息附加至 log 後的通知。這就像 Unix 工具的 tail -f 一樣,當檔案被寫入後你會同步看到內容一樣。

這裡 log 也能使用 partition (2020 Day 27) 來應付更高的吞吐量,不同分區由不同的節點負責,每一個分區都是獨立的讀取和寫入,一個主題可以被定義為一組分區,這種方法如下圖 11-3 所示:

每一個分區,broker 會分配一個逐漸累加的序列號到每一條訊息上,稱為 offset,就是下圖方框內的數字,因為 log 只能附加上去,所以每一個分區的訊息皆是完全排序,但不同分區的順序無法保證。

Apache KafkaAmazon Kinesis StreamsTwitter DistributedLog 皆是基於 log 的訊息代理。

消費者 offset

offset 讓消費訊息的追蹤更簡單了,比較一下各訊息的 offset 跟消費者當前的 offset 大小就好,也因此 broker 就不用在花費力氣追蹤各訊息的 acknowledgments 了,它只要定期記錄消費者的 offset 就好,進而提高訊息代理的吞吐量。


上一篇
Stream Processing (1-1) - Transmitting Event Streams
下一篇
Stream Processing (2) - Chande Data Capture
系列文
資料工程師修煉之路 Part II30

尚未有邦友留言

立即登入留言