Lambda Architecture(批次層與即時層)
Lambda Architecture(批次層與即時層)
Lambda architecture 是把同一份統計分成兩條路徑計算的做法:批次層(batch layer)定期從完整的原始事件重算出正確的數字,即時層(speed layer)在事件發生的當下累加,補上批次層還沒算到的最近那一段。查詢時由合併層(原始定義稱為 serving layer)合併兩者:較早的時段讀批次層,最近的時段讀即時層。批次層的結果是權威,即時層的數字遺失或偏差時,等批次層算到那一段就被取代。它和 Materialized View 同樣是預先算好的結果,差別在於 materialized view 只有一份、刷新前讀到的是舊值;兩條路徑的做法用即時層填補刷新之間的空檔。其他中文資料常寫作 Lambda 架構。
概念位置
| 路徑 | 輸入 | 結果的性質 | 常見載體 |
|---|---|---|---|
| 批次層 | 保存期限內的全部原始事件 | 可重算、規則改了可以全部重新算 | 資料庫裡的彙總表、資料倉儲的排程查詢 |
| 即時層 | 事件發生當下的那一筆 | 只能累加、不能修正,遺失就是少算了 | Redis 的計數與 HyperLogLog、串流處理的視窗聚合 |
兩條路徑寫兩份計算邏輯,是這個做法主要的維護成本。Kappa architecture 只留一條串流路徑,要重算時從事件記錄的開頭重播;適合事件本身長期保存在可重播的事件記錄裡(例如 Kafka)的系統。把事件長期保存、以重播重建狀態的設計見 Event Sourcing。
可觀察訊號與例子
- 同一個時段兩份數字不一樣:即時層只累加原始的點擊,批次層依規則排除機器人之後才計數,同一個小時在即時層看到的數字比較大。介面上要標示即時層的數字是「未分類、尚未定案」,或兩者的口徑一致。
- 最近幾分鐘的數字突然變小:即時層的資料庫重啟或切換節點,遺失了最近的累加。等批次層算到那一段就補回來;若批次層也偏低,問題出在原始事件的寫入,不在即時層。
- 切換點的重複或缺漏:合併時以「批次層已經完成到哪一個時段」為界,界線以前讀批次層、以後讀即時層。界線用「現在減一小時」這類固定值時,批次層落後的那一段會兩邊都沒有。
實例:短網址的點擊在轉址時以 Redis 的 HINCRBY 依連結與小時累加,後台看目前與前一個小時的數字時讀它;更早的時段讀資料庫裡依原始事件重算的小時表。詳見 1.18 高頻計數的寫入與彙總:熱點列的鎖、只新增的事件、可以重跑的彙總與重送的事件〈Redis 在計數、去重與互斥裡的位置〉。
設計責任
先確認需求方真的需要比批次層更新得更快的數字:批次層每分鐘重算一次就夠用時,即時層只增加一份要維護的邏輯。採用時寫下三件事:哪一層是權威、兩層的界線由什麼決定、兩層的計數口徑有沒有差別以及介面怎麼標示。即時層的資料不需要備份,它的遺失由批次層吸收。