Apache Kafka不適用於Event Sourcing!

banq發表於2018-09-05
Apache Kafka是一款很酷的產品,但如果你考慮將其用於事件溯源,建議你應該再考慮一下。

Kafka是一個在生產者和消費者之間傳遞訊息的絕佳工具,可選的主題永續性能讓你永久儲存訊息,是的,永遠,如果你願意。

因此,如果你的訊息是事件,可以將Kafka用作事件儲存或事件日誌,但它實際上不適合用於事件溯源。

原因如下:

1. 載入當前狀態
當服務收到請求對事件源實體進行狀態更改的命令時,我們首先需要重新建立該物件的當前狀態,我們透過從事件儲存載入該特定實體ID的所有先前事件,然後將它們重新呼叫我們的領域物件中的相應方法,快速播放事件直到當前狀態。

在Kafka中載入像這樣的特定實體的事件並不容易。主題通常以 “ 訂單 ”,“ 付款 ”或“ 通知 ” 等實體型別為中心進行分割槽,因此我們必須檢查所有 “ 訂單 ”的所有事件,並按其ID過濾它們以得到一個“ 訂單”實體的狀態,雖然這是可能的,但它並不實用。

一種替代方案是每個實體有一個主題,但我們最終可能會遇到數以千計的主題,而且最重要的是,訂閱服務的下游需要一種方法來自動發現每個新實體的新建立的主題,這 不太實際。

2. 一致的寫操作
當我們的實體狀態被重新建立時,是時候執行傳入命令所請求的業務邏輯了,如果業務邏輯失敗,我們會向客戶端返回錯誤,但如果成功則會發出新事件。在這種情況下,我們必須能夠將新事件儲存到我們的事件儲存中,同時保證在此期間沒有為此特定實體ID儲存其他事件,否則我們可能會破壞領域物件的一致性。

OCC來救援

保證寫入一致性的一種方法是利用事件儲存的樂觀併發控制,正確的事件儲存為使用者提供了一種方式,即“僅當實體的版本仍為x時才儲存此事件”,Kafka不支援這一點,來自該領域專家的建議解決方法似乎是在其前面放置一個“資料庫”以提供一致性控制點,雖然在某些情況下這個建議可能是一個可行的解決方案,但從長遠來看,選擇更適合特定問題的工具可能更明智。

3. 單寫
獲得一致性的另一種方法是確保序列化寫入,即使用單寫入器原則,這意味著我們確保關於特定實體ID的所有寫入都發生在單個執行緒上。我們可以透過使我們的生產者堵塞等到其釋出的事件被提交且可用,這種設計會對效能產生嚴重影響。

它適合嗎?
那麼,Kafka在事件源架構中是否有一席之地?也許,大概,它可能是你的事件儲存的一個很好的補充,作為將事件傳輸到下游查詢服務或讀取模型的方式。

但是,在為我們的系統新增大量複雜的基礎設施時,我們應該始終小心 - 所有這些都需要付出成本,因此請確保它足以滿足你手頭的問題!

Apache Kafka is not for Event Sourcing – SERIALIZE

相關文章