事件溯源超越關聯式資料庫 - confluent

banq發表於2021-09-13

我一直覺得事件溯源很吸引人。我們在開發人員的大部分時間裡都在將資料儲存在資料庫表中——以一種完全不同的方式來做這件事似乎幾乎是深不可測的。然而,這就是事件溯源。它有明顯的好處,但還有許多潛在的問題。
首先,您需要確定事件溯源是否適合您要解決的問題。為您的系統決定是使用事件源還是基於 CRUD 的資料解決方案類似於決定是使用笛卡爾座標系還是極座標系來解決數學問題:兩者都可以用於解決問題,但有些問題更適合一個座標系(例如,行星繞太陽的運動最好用極座標解決)。
 

傳統事件溯源(約 2000 年代初)
為了更好地理解傳統意義上的事件溯源,您可以首先將其與正常的 CRUD 流程(例如可能與電子商務購物車一起使用)進行考慮。假設您將三條褲子新增到購物車中,稍後改變主意並刪除兩條,然後繼續結賬時只帶了一條。在 CRUD 模型中,只會將最終結果儲存在資料庫中,因此您只訂購了一條褲子的事實將被記錄下來,僅此而已。但是在事件溯源模型中,你在這個過程中所做的每一個動作都會被儲存起來,即第一個新增三條褲子的動作,第二個刪除兩條褲子的動作,以及購買單條褲子的最後一個結賬動作. 您正在有效地收集使用者活動的時間序列——系統本身的日誌。
您幾乎可以使用任何資料庫執行事件溯源。基本上,您建立一個表並按事件發生的順序附加事件。最後,您查詢最有可能按客戶 ID 或會話 ID 聚合的事件,然後執行“按時間順序減少”以過濾與您想要提供服務的檢視相關的事件。
事件溯源優勢有幾個方面。

  • 首先,有證據優勢——“會計師不會用橡皮擦”。事件溯源為您的系統建立了一個類似於版本控制的審計,它允許您確定,例如,為什麼在特定時間點出現問題。
  • 這導致了第二個優勢:“可重玩性”。如果您的資料被錯誤損壞,例如,一個可能影響整個應用程式系統的資料,您可以返回到錯誤出現之前的某個點。收集這麼多資料的最後一個好處是,您可以將其輸入到分析系統中,無論是用於機器學習還是其他型別的分析。回到購物車的概念,因為購物車給了我們非常真實的使用者行為記錄,

因此,傳統的事件溯源及其優勢相對簡單,但更復雜的架構(需要使用 Apache Kafka  等工具進行大規模擴充套件和流式傳輸的架構)是否也能享受到它的優勢?
 

使用 Kafka 和 CQRS 進行事件溯源
當您開始使用像 Kafka 這樣的流處理器來推理事件源時,很明顯,按時間順序排列的事件會進入日誌。但是當你開始查詢時,事情變得有點奇怪:你如何在 Kafka 中執行必要的事件查詢,因為它缺乏內部查詢 API?(這實際上是網際網路上的一個常見問題,啟發了許多部落格文章。)
解決辦法是 CQRS(命令查詢責任分離),這是一種事件溯源形式,它將執行“命令”(更改狀態)的系統部分與“查詢”(返回值)的部分分開。CQRS 的另一個重要方面是在寫入時立即完成按時間順序的縮減,因此檢視在提供服務之前非同步更新。
所以 Kafka 持有狀態,但它被推送到流處理器 API(通常是ksqlDB),在那裡建立適合特定用例的物化檢視。事件在很大程度上仍然是儲存模型,並且可以隨時從底層事件重新生成檢視。
 

即使使用 CQRS,事件溯源也很困難
在 CRUD 系統中,通常只有一個應用程式和資料庫,但在 CQRS 中,有更多活動部件:一個應用程式、一個 Kafka 主題和一個檢視——即使是最簡單的形式。沒有模式遷移,所以隨著事件模式隨著時間的推移而演變,許多不同的模式最終會出現在日誌中。並且複雜性隨著模式的數量而增加,因為每個模式需要不同的解析程式碼。最後,CQRS 的一個關鍵因素是它只有最終一致,這意味著您不一定能讀取自己的寫入。
因此,CQRS 有一點額外的複雜性,但該模型適用於許多不同型別的用例。
例如,《紐約時報》將報紙自 1851 年創刊以來的每一次編輯、影像、文章和署名都儲存在一個 Kafka 主題中。原始資料儲存為事件,然後服務將其轉換為要在網站上交付的檢視。內容來源的 CMS 實際上並不需要立即與服務層保持一致。如果需要不同的檢視,日誌會被倒回,並透過重放來建立一個新的檢視。
 

什麼時候您仍然需要 CRUD 
順便說一句,如果 CRUD 對您的應用程式有意義,那麼有一些方法可以獲得事件溯源的一些好處。您可以使用老式觸發器,或者您可以更改資料捕獲 (CDC) 您的資料,如果您想稍後將其匯入 Kafka,這是一個不錯的選擇。透過這些選項,您將獲得一些有益的事件溯源屬性,但不是全部 — 它仍然是證據,您可以進行分析,但您將無法獲得可重玩性(如果您有一個 Web 應用程式,這可能不會)事情)。您可以嘗試的另一個選項是雙時態資料庫,這是一種通常被低估的資料庫。
 

CQRS隨著資料的流動而自成一體
單體應用程式受益於事件,但當資料必須移動時,它們真的變得很重要——當應用程式的不同部分需要相互合作並共享資料時,可能在全球範圍內。
一個例子是航班預訂系統,它的讀取次數可能是寫入次數的 10,000 倍,並且是全球性的。您可以嘗試使用全域性分散式資料庫來設定系統,但這不一定是最有效的方法,因為無論資料是否來自全域性一致的資料庫,讀取本身最終始終是一致的——因為瀏覽器快取和其他因素。最重要的是,當您預訂航班時,您肯定會得到預訂。因此,將讀取和寫入分開並讓寫入到一個一致的地方是有意義的,但讓讀取去一個最終一致的地方。
 

事件流適合的地方
事件流是事件源和 CQRS超集。它的事件使用共享資料模型,這意味著許多服務可以訪問它們。它不僅建立檢視,還實時將來自不同來源的資料縫合在一起。
它還具有多語言永續性,這意味著每個服務都可以選擇儲存資料的位置和方式。這開啟了事件驅動處理的可能性,事件由此觸發其他動作——這確實是事件流的核心。
總之,使用資料庫進行事件溯源顯然是一種非常好的模式:它適用於單體應用並且已經存在很長時間了。CQRS 是一種改進,但對於需要在許多服務之間擴充套件和共享資料的微服務架構來說,具有這兩種元素的事件流是最佳選擇。
 
banq:其實可以在經典事件溯源與CRUD關聯式資料庫模型之間取得一個平衡,將事件溯源看成是一種明細表、任務表或領域事件集合,這種新的中庸模式沒有經典事件溯源的僵化,也就是可以刪除條目的,不像事件溯源那樣不可以刪除,只能追加,這種僵化的教條帶來問題是,事件溯源庫中有大量人為操作印跡,這種印跡留痕只有在安全追溯有用,這屬於大資料統計分析領域,不屬於業務模型領域,再者歐洲有隱私法律,使用者提出要求後,其運算元據必須不留痕地刪除,否則違法。
新的中庸模式可以利用傳統關聯式資料庫儲存領域事件集合,降低系統複雜性,教條主義會增加複雜性,複雜性是最大敵人。
 

相關文章