串流處理 (Stream Processing)

★★★★★Reviewed

FromDDIA

📚 From the Books

串流處理 (Stream Processing)Batch & Stream

批次處理跑在有界 (bounded) 的固定資料集上;串流處理跑在無界 (unbounded)、永遠不會結束的事件流上。難點不在「逐筆處理」,而在時間怎麼算、視窗怎麼切、遲到的事件怎麼辦

🧠 Intuition

TIP

把它想成「永遠跑不完的批次作業」。輸入永遠在增加,所以你無法等資料「到齊」才算結果——只能在不完整的資料上持續產出、並準備好被後來的事件修正。

⚖️ Tradeoffs

Log-based broker (Kafka) vs 傳統 AMQP/JMS
  • 傳統 message queue(RabbitMQ、ActiveMQ):訊息被消費後即刪除,broker 記錄「誰確認了哪則」,適合 task queue 式的工作分派。
  • log-based broker(Kafka、Pulsar):訊息持久化成 append-only log,consumer 各自維護 offset,可重放歷史、可多組獨立消費。
  • 取捨:log-based 容易重播與多訂閱、吞吐高,但「單則訊息處理很慢」的場景不如 AMQP 那種逐則 ack 來得靈活(一則卡住會擋住整個 partition)。
  • 經驗法則:要事件溯源 / 多下游 / 可重放選 log-based;要任務分派 / 優先序 / 逐則重試選傳統佇列。
事件時間 (Event time) vs 處理時間 (Processing time)
  • event time:事件實際發生的時間(裝置上打的戳)。processing time:事件被系統處理的時間。
  • 兩者會分歧:網路延遲、裝置離線後補傳、consumer 重啟追進度,都會讓事件「遲到」。
  • 用 processing time 算視窗最簡單但會說謊:一次 consumer 卡頓就會讓某分鐘的計數暴增(其實是補算)。
  • 正確做法用 event time,但代價是你永遠不確定某個視窗的事件是否到齊——這就是 watermark 要解的問題。
視窗類型 (Windowing)
  • Tumbling:固定長度、不重疊(每 1 分鐘一桶)。每個事件只落在一個視窗。
  • Hopping:固定長度但有固定步長、會重疊(長 5 分鐘、每 1 分鐘滑一次)——同一事件落在多個視窗,常用於滑動平均。
  • Sliding:以每個事件為中心、看「前後 N 時間內」的其他事件,邊界由事件本身觸發。
  • Session:沒有固定長度,用「不活動間隔 (gap)」切分——一連串密集事件算一個 session,靜默超過閾值就關窗。適合使用者行為分析。
Watermark 與遲到事件
  • watermark 是一個推進中的斷言:「event time 早於 t 的事件,我認為都到齊了」——於是可以關閉 ≤ t 的視窗、輸出結果。
  • 取捨永遠在延遲 vs 完整:watermark 推得快→結果出得早但容易漏掉遲到者;推得慢→結果更完整但延遲高。
  • 遲到事件(晚於 watermark 才到)的處理策略:直接丟棄、或保留視窗狀態一段 grace period 後發修正值 (retraction/update)
  • 沒有完美解:分散式時鐘下「資料到齊」本質上不可知,只能用啟發式逼近。
Stream–stream join vs Stream–table join
  • stream–stream join(如點擊流 join 曝光流):兩邊都是流,必須在時間視窗內配對,且要為兩邊維護狀態緩衝——狀態大、要設過期。
  • stream–table join(流 enrich 一張維度表):用事件去查一張會變動的表(如 user id → profile)。表本身常是另一條 CDC 流重建的物化狀態。
  • 關鍵陷阱:join 的結果取決於你用了哪個時刻的表狀態。維度表後來改了,重放同一段流會得到不同結果——這就是為什麼要把表也當成「帶時間的變更流」來看。

🔑 Takeaways

✍️ My Notes

2026-07-01

  • Q: 既然 event time 比 processing time 準,為什麼不一律用 event time?
  • A: 因為 event time 把一個棘手問題攤到檯面上:你永遠不知道某個視窗的事件是否到齊。用 processing time 時,「現在這一分鐘過了」是個明確訊號,視窗可以乾脆地關閉;用 event time 時,遲到的事件可能在幾秒、甚至幾小時後才到,你得靠 watermark 猜「應該到齊了」,還得決定遲到者要丟棄還是發修正。換句話說 processing time 簡單但會在系統抖動時說謊;event time 誠實但逼你正面處理不確定性。生產上常見折衷是 event time 開窗 + 合理 watermark + 一段 grace period 收遲到者,超過才丟。

📖 Further Reading

🔗 Dive Deeper