l

2022年7月12日 星期二

事件溯源(15):Apache Kafka可以當做Event Store嗎?

July 5 19:02~20:09

圖片擷取自維基百科

 

前言

Teddy剛開始接觸Event Sourcing時,就是使用EventStoreDB,後來在ezKanban中也支援用PostgreSQL當作Event Store。但是在YouTube聽演講或是看網路文章,有時會發現有人把Apache Kafka做為Event Store。前陣子Teddy在看Apache Pulsar的書,Pulsar是和Kafka類似的Event Broker軟體但感覺好像架構又設計的更好一些。當時Teddy就想:「可以拿Pulsar當Event Store嗎?」

Kafka與Pulsar在message-oriented system中被大量使用,它們具有可靠、高效、可拓展與可永久儲存訊息的能力,很自然地會讓人想把它們當成Event Store使用。Teddy在網路上沒有找到Pulsar是否可做為Event Store的相關討論,倒是看到一篇文章<Apache Kafka Is Not for Event Sourcing>。因為不少作Event Sourcing的人可能也都會有這樣的疑問,Teddy今天就介紹這篇文章中提到不適合的兩點理由。

 

***

載入狀態

在Kafka中,訊息放在Topic裡面,然後Topic通常以entity type做為分類。以ezKanban的Core Domain為例,如果用Kafka當Event Store,會有Boards, Workflows, Cards, Tags這四個Topic。假設要讀取出某張Card,需要從Cards Topic讀出所有卡片的所有訊息,然後依據card id過濾出所需卡片的相關訊息。雖然這樣做是可行的,但有點不切實際,可能會有效率低落的疑慮。

如果學習EventStoreDB的做法,一個Aggregate instance享有一個Topic,這麼一來就會有為數非常可觀的Topic在Kafka伺服器上面。姑且不論Kafka能不能支撐大量的Topic,對於subscriber而言,要如何接收的想要的訊息(領域事件)?舉個例子,想要知道所有的CardMoved事件,在EventStoreDB中,只需要從$et-CardMoved這個系統自動投影出來的event stream就可以拿到。但在Kafka的情況下,subscriber需要去註冊所有Card instance的Topic才能拿到所有的CardMoved事件,這有點窒礙難行。

***


一致性寫入

文章中提到第二點不適合的理由是Teddy在<事件溯源(7):樂觀鎖>介紹過樂觀鎖的問題。在併行處理的系統中,為了避免寫入衝突,通常會採用樂觀鎖的機制,在一般的關聯式資料庫或是EventStoreDB都支援。但依據該文章的說法,Kakfa的Topic寫入沒有支援樂觀鎖,因此也不合適做為Event Store使用。

 

***

使用時機

Kafka或Pulsar這種Event Broker不是說在Event Sourcing系統中都不能使用,只是不要拿來當作Event Store。如下圖所示,領域事件還是存在EventStoreDB或是其他類似的資料庫,至於要往外(下游,downstream)傳遞的領域事件,可以轉發至Kafka或Pulsar。

換句話說,把Kafka或Pulsar拿來當作跨Bounded Context或是跨服務的訊息傳遞,不要拿來做Event Store。

 

 

***

 

下集預告

這一集內容雖然比較簡短,但卻是很重要個觀念,因為選對Event Store當你上天堂,選錯Event Store會讓你住套房。下一集回頭介紹一組相關的基礎觀念:在最終一致性(eventual consistency)的情況下,事件必須滿足event ordering與at least once這兩個條件,以及event handler要如何達到idempotent。

***

友藏內心獨白:很想用一個工具打通關。

沒有留言:

張貼留言