為什麼我們放棄使用Kafka Streams實現全部的事件溯源?-Mateusz

banq發表於2022-03-25

我們並不是說事件溯源總是一個糟糕的選擇。這是一個真正強大的概念。但是,您應該警惕它可能給您的專案增加的複雜性。我們的看法是你不應該用它來解決所有型別的問題,而應該將它應用到選定的業務領域(它可能對所有型別的技術和技巧都是通用的)。
Kafka Streams 可能對我們來說更加陡峭的學習曲線,儘管我們仍然相信它可能是使用 Kafka 和 Java 進行資料流傳輸的絕佳解決方案。
 
產品
在不透露太多資訊的情況下,我可以分享一下,我們正在談論構成更大系統一部分的金融科技產品。其主要目的是跟蹤使用者的資金流向,處理銀行轉賬和其他金融業務。
在改造之前,該軟體使用事件溯源並使用 Kafka 作為真相的來源。我們大量使用 Kafka Streams 庫來處理、聚合和儲存資料。該堆疊基於:
  • Spring Boot
  • Kafka Streams, Spring Kafka,
  • Spring Web, Data, Security
  • PostgreSQL (just for query-only projections)
  • 模組化單體架構
  • AWS
  • Protobuf


但是我們現在從基於 Kafka Streams 的事件溯源切換到以資料庫作為資料儲存的事件驅動系統。
  • 以前,Kafka是我們的真理之源。所有代表系統中發生的變化的訊息(事件)都被無限期地儲存在Kafka中。
    現在,好的舊資料庫儲存了實體的當前狀態,而Kafka只是幫助我們在變化發生後傳播資訊。我們對待Kafka更像一個訊息中介,所以訊息是短暫的。
  • 我們引入了同步的REST APIs,之前所有的東西都是透過Kafka進行非同步的。
  • 到目前為止,我們不再使用Kafka Streams庫,而是使用標準的消費者和生產者,這已經足夠。
  • 我們從Protobuf切換到Avro
  • 這根本不是什麼變化,但我們決定繼續實施事件承載狀態轉移模式。
  • 對於一個單一的用例,我們將能夠模擬事件溯源:我們將關鍵的訊息儲存在資料庫中,我們可以將它們轉儲到Kafka上,以備我們需要重新播放所有的訊息。


好處:
  • 新的期望是比最初假設的更快地實現更大的規模。這將意味著更少的時間來實際學習使用和操作事件源系統。
    因此,事件的數量最終會更大,這反過來會導致更長的重播時間來從事件中重建狀態。這可以透過增加分割槽數量來解決,但是更改分割槽數量並不是那麼容易。
  • 備份儲存在資料庫中的資料比備份 Kafka 訊息和偏移量要容易得多。許多經過實戰考驗的解決方案都是現成的。
  • 在使用Kafka Streams時,我們在實現零停機時間方面遇到了一些麻煩(在新版本中可能有所改進)。REST+DB讓它變得非常容易。
  • 事件源很困難(尤其是與Kafka流結合時)。很難很好地學習這個概念,當涉及到實施時,很難向其他人解釋它。為了我們的新團隊成員,也為了其他工程師,更簡單的方法似乎更明智。
  • 我們瞭解到,對事件來源的系統進行推理比較困難。在一個潛在的危機中,可能需要更長的時間來發現發生了什麼並恢復服務。

 

一致性
以前只在Kafka中儲存所有的資料,我們能夠使用Kafka Transactions來實現精確的一次性語義,從而實現一致性。
現在,當我們將變化的結果儲存在資料庫中,並需要將變化的事件釋出到Kafka中時,我們無法在一個事務中完成。
我們正在考慮使用Outbox模式來規避它。
更多發件箱
  

審計跟蹤
以前因為我們無限期地儲存了所有的事件,所以我們有一個完整的歷史,可以瞭解手頭系統中發生的事情。因此,不需要審計跟蹤表或其他審計日誌--沒有資訊丟失。
現在,我們需要格外小心,不要失去對系統中發生的重要行動的追蹤,因為有些行動可能只作為短暫的Kafka訊息留下痕跡。
資料庫只儲存了系統的當前狀態。
幸運的是,有行之有效的方法來解決這個問題。

新服務:歷史資料
引入需要歷史資料的新服務在以前是很簡單的。他們可以直接從最早的偏移量中消費事件,然後重放歷史。
有了新的事件驅動的解決方案,這種情況將更難處理。

嘗試一種新的方法並發展你的技能總是很有趣的。但作為工程師,我們同時也需要務實,不斷地重新評估我們的選擇。
雖然圍繞著在資料庫中儲存資料的比較傳統的解決方案看起來比較枯燥,但從另一方面來說,它可以讓我們把更多的時間花在業務功能上,而減少技術上的困難。
 

相關文章