
「資料變化要能即時反映出來,並透過事件的形式進行串接。」基於這樣的概念,我們需要在異動資料抵達系統時,在毫秒或秒級就處理完成。今天就逐步拆解概念,一一掌握技術名詞吧。
事件是指系統中發生的任何可觀察的行為或狀態變化。當事件發生時,通常會伴隨一些與之相關的資料產生。例如,在應用程式中使用者採取的行動,檢視頁面或訂單狀態更新都可以視為事件。事件也可能源自於伺服器 (server) 的日誌 (log)。
事件是不可變的 (immutable),表示它只描述某個時間點發生的某件事情的細節。而日誌會把所有系統上的歷程全部記下來,只增不減 (append only)。
若我們把事件視做一種帶有資料的訊息 (message),那麼訊息佇列 (message queue) 是一種用來在不同系統或應用程式之間傳遞訊息的架構。它核心概念是:訊息產製者 (producer) 將訊息放入佇列,而訊息消費者 (consumer) 會從佇列中提取訊息進行處理。這是一種**非同步 (Asynchronous) **的通訊模式,產製者不需要等待消費者完成處理,也不像輪詢 (Polling) 一樣,輪詢地越頻繁,能返回新事件比例就越低,而額外開銷也就越高。
同步 (Synchronous) 就像打 API 一樣,發出請求 (request) 之後必須等到回應 (response) ,中間若有連線中斷,資料就會遺失。
訊息佇列系統具有以下特性:
市面上有許多工具搭建訊息佇列系統,包含開源工具 (RabbitMQ、Redis、Kafka) 或雲端服務 (GCP Cloud Pub/Sub、AWS Amazon SQS) 可以搭建訊息佇列系統。
如果以 Day 03 提到的網購服務新創團隊為例,資料流複雜性與資料量級對一般的 message queue 可能會超出負擔。而 Kafka 透過使用 zero-copy 方法,直接將 bytes 從檔案系統傳輸到網路緩衝區 (network buffer),繞過應用程式緩衝區 (application buffer),是吞吐量 (throughput) 可以明顯地提升的原因。
Kafka 採用分散式架構方便水平擴張,且將資料存放於硬碟空間,可以長時間保存資料,這些特性針對巨量資料串流處理 (big data streaming processing) 處理非常實用。
接下來,我們要把這些概念轉成元件,拼湊出一條即時資料處理管線。
首先,在 Kafka Connect 中啟動一個 Debezium (開源的 CDC 平台)。這個 Debezium 負責監聽來自資料源的變更日誌,轉譯成 INSERT, UPDATE, DELETE 等 Kafka 事件後,最後由 Kafka Connect 將這些事件資料即時地傳送到 Kafka。
{
"schema": {
"type": "struct",
"fields": [ ... ]
},
"payload": {
"before": null,
"after": {
"id": 1001,
"first_name": "John",
"last_name": "Doe"
},
"source": {
"version": "1.6.0.Final",
"connector": "mysql",
"name": "my-app-db",
"ts_ms": 1623863456000
},
"op": "c",
"ts_ms": 1623863457000
}
}
before:變更前的資料。如果是 DELETE 操作,這裡會顯示被刪除的資料;如果是 INSERT,則為 null。after:變更後的資料。如果是 UPDATE 或 INSERT,這裡會顯示新資料。op:操作類型,c 代表 create,u 代表 update,d 代表 delete。因此,Debezium 提供的 CDC 服務就是一種來源連接器 (Source Connectors),類似訊息產製者的角色,負責把變更事件發送到訊息佇列 Kakfa。對應的目標連接器 (Sink Connector) 則作為訊息消費者的角色,把資料從 Kakfa 取走,送往後續的目的地,例如備份資料庫、應用程式資料湖、資料倉儲等。

圖/RFM 分析的上游透過 Debezium + Kafka 實現資料源變化即時捕捉管線。簡書廷製。