Hi 各位好,今天的文章屬於導讀性質,我將帶領大家讀 Jay Kreps(LinkedIn 原首席工程師,現 Confluent CEO)在 LinkedIn 時期所留下的經典文章 The Log: What every software engineer should know about real-time data's unifying abstraction。
這篇文章的標題本身就是核心訊息:Log 是即時資料世界裡的統一抽象。如果說資料庫是我們慣常理解的「狀態的載體」,那麼 Log 就是「狀態的生成過程」。理解這一點,將徹底改變我們對資料庫、分散式系統與事件流處理的認知。
Jay Kreps 加入 LinkedIn 的時間點非常特別,正好是公司從 集中式資料庫過渡到分散式系統 的轉折期。當時的挑戰不只是規模的擴展,而是如何處理「一致性」「資料延遲」「跨系統整合」這些比單一資料庫更複雜的問題。也是在這個時候,Jay Kreps認識到log的重要性。
相信每個進行過系統管理的工程師都知道日誌的重要性。日誌,是一個帶有時間序列的紀錄文本,它實時記錄了關於系統你所需要知道的每一件事。從服務啟停、錯誤追蹤,到流量尖峰的觀察,log file 就像系統的日記,讓工程師能夠在混亂中回溯因果。
而在資料庫世界裡,也有與系統 log 類似的存在:binlog 與 WAL(Write-Ahead Log)。
如同 Jay Kreps 描述 log的起源很早,甚至不被視為一項重要的發明。而資料庫中的binlog則利用日誌存在時間與順序附加的特性記錄下了每一個交易內容。由於這個特性,機器可讀日誌的概念在很大程度上僅限於數據庫內部。
換言之,每一筆交易內容,最終可以成為一個完整的狀態
使用日誌作為資料訂閱機制,看似歷史上的偶然;最初,log 主要用於資料庫內部,作為保持一致性與恢復的工具。但正因其 append-only、有序、可重播 的特性,這種抽象非常適合支援各種訊息傳遞、資料流與即時資料處理。換句話說,雖然 log 起源於資料庫,但它的設計理念,恰好為分散式系統和流式架構提供了理想的基礎。
當 LinkedIn 從集中式資料庫過渡到分散式架構時,挑戰變得更具體:如何在多個節點之間保持資料一致性?
這時 log 的價值變得尤為明顯。Jay Kreps 提出了 State Machine Replication Principle——如果每個節點都是相同且確定性的(deterministic)過程,並且以相同順序接收相同事件輸入,那麼它們最終的狀態就會一致。換句話說,分散式系統的核心問題,可以簡化為「如何讓每個節點收到相同的事件序列」。
簡單來說,State Machine Replication Principle 就是「狀態複製原則」:假設每個節點接收到相同資料流,那麼最終狀態將保持一致。
log 在分散式系統中的價值,主要體現在兩個方面:
因此,分散式系統中的一致性問題,不再是「多個狀態如何同步」,而是「如何確保 log 的順序一致」。Log 成為分散式一致性的最小抽象單位。
更直觀地說,log 不只是資料記錄,它本身就是 決策序列(sequence of decisions)。透過 log,系統可以將非決定性因素(如不同節點的計算順序)「壓縮」掉,只留下單一、可靠的事件序列。無論是 active-active 模型(每個節點獨立處理請求)還是 primary-backup 模型(單一領導節點排序並寫入 log),log 都是保持副本同步、實現一致性的核心工具。
甚至可以把 log 的時間戳想像成每個副本的「時鐘」:只要知道副本處理到哪個 log 條目,就能準確描述它的狀態。這種抽象不僅支援分散式資料庫,也成為訊息系統、資料流與即時運算的基礎設計思維——正是 Kafka 等系統的核心哲學。
傳統資料庫之間的同步,多以 批處理(batch processing) 為主:系統會先累積一定量的資料,再一次性讀取、轉換,最後寫入下游系統。這種方式雖然實現簡單,但存在天然的時間延遲——資料並非即時更新,下游系統看到的狀態總是滯後於源頭。
換句話說,批次處理的同步存在時間差,資料狀態只能以間隔更新,無法即時反映系統變化。
理解了 log 的 狀態複製原則 之後,我們可以利用資料庫的 binlog 進行同步,這也是目前常見的資料庫 slave 模式。事件流將每一筆交易、狀態變更或使用者操作,視為一個個 獨立事件,即時寫入 log,並可供多個下游系統跟進。
事件流的價值,在於將資料變更拆解為 有序、可重播的事件序列。透過 log,不同節點可以共享相同的事件時間線,消除非決定性因素,使每個節點即使獨立運算,也能保持一致狀態。
可以這麼理解:log 的累積形成了資料庫,而資料庫本身,也可以被視為 log 的聚合。
正如前面所說,log 的累積形成了資料庫,而資料庫本身,也可以被視為 log 的聚合。更精確地說,資料表(table)與事件 log 之間存在一種有趣的二象性:
這個過程也可以反過來:如果資料表接收更新,我們可以將這些變更記錄成一個「changelog」,提供近乎即時的副本更新。從這個角度看,資料表與事件 log 互為映射:資料表支援「靜態資料」(data at rest),log 則捕捉「變更事件」(changes)。完整的 log 不僅包含最終資料表的內容,也能重建所有曾存在的版本,宛如每一個歷史狀態的備份。
這種思維與版本控制系統有驚人的相似性:版本控制記錄一連串 patch(變更),而使用者操作的是當前快照(snapshot),副本同步也是透過 log 進行。類似地,分散式資料系統管理狀態變更時,log 扮演了核心角色,使多個副本能一致更新,並追蹤歷史。
看似簡單,但將這種觀念抽象化並轉化為可落地的工程方法,正是我們系列文章要探討的主題
今天的導讀帶領大家閱讀了 Jay Kreps 的經典文章 The Log: What every software engineer should know about real-time data's unifying abstraction,從中我們可以理解到:
總結而言,log 不只是資料的記錄,它是一種將系統變更抽象化、可重播與可同步的核心工具。透過這種抽象,我們能提煉出可落地的工程方法,這正是我們系列文章所關注的主題:抽象在工程中的具體價值,也是我們在工程實務中不斷追求與學習的核心理念。
理解今天所分享的內容,有助於深化我們對資料庫與分散式系統的認知,也為設計訊息系統、事件流架構及即時運算提供理論與實務基礎。希望這篇導讀能對各位的學習有所幫助。
感謝各位的閱讀,我們明天見!