為什麼我們放棄使用Kafka Streams實現全部的事件溯源?-Mateusz
我們並不是說事件溯源總是一個糟糕的選擇。這是一個真正強大的概念。但是,您應該警惕它可能給您的專案增加的複雜性。我們的看法是你不應該用它來解決所有型別的問題,而應該將它應用到選定的業務領域(它可能對所有型別的技術和技巧都是通用的)。
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訊息留下痕跡。
資料庫只儲存了系統的當前狀態。
幸運的是,有行之有效的方法來解決這個問題。
新服務:歷史資料
引入需要歷史資料的新服務在以前是很簡單的。他們可以直接從最早的偏移量中消費事件,然後重放歷史。
有了新的事件驅動的解決方案,這種情況將更難處理。
嘗試一種新的方法並發展你的技能總是很有趣的。但作為工程師,我們同時也需要務實,不斷地重新評估我們的選擇。
雖然圍繞著在資料庫中儲存資料的比較傳統的解決方案看起來比較枯燥,但從另一方面來說,它可以讓我們把更多的時間花在業務功能上,而減少技術上的困難。
相關文章
- 使用Kafka實現事件溯源Kafka事件
- 從入門到放棄 - 事件溯源事件
- 為什麼我們放棄了 Vue?Vue 和 React 深度對比VueReact
- GitHub:我們為什麼會棄用jQuery?GithubjQuery
- 為什麼放棄jQueryjQuery
- 我為什麼放棄MySQL?選擇了MongoDBMySqlMongoDB
- 使用Spring Boot和Kafka Streams實現CQRSSpring BootKafka
- 為什麼我們放棄 Python 而選擇 Go?(getstream.io 的架構變遷)PythonGo架構
- [譯] 為什麼我放棄了 React 而轉向 Vue。ReactVue
- 為什麼都放棄了LangChain?LangChain
- 為什麼我們從RabbitMQ切換到apache kafka?MQApacheKafka
- 使用Kafka Streams構建事件源系統的經驗Kafka事件
- 為什麼我們不使用GraphQL? - Wundergraph
- GC是什麼?為什麼我們要去使用它GC
- 使用Datomic實現沒有麻煩的事件溯源事件
- 從入門到放棄,我們為何從 Blazor 回到 VueBlazorVue
- 為什麼要在2021年放棄ExpressJS -DEVExpressJSdev
- 為什麼創業公司反而適合使用微服務+事件溯源? -zimarev創業微服務事件
- 為什麼 husky 放棄了傳統的 JS 配置JS
- 我們為什麼要使用CRM系統?
- 為什麼我們做分散式使用Redis?分散式Redis
- 使用EventStoreDB實現事件溯源的Python開源專案事件Python
- 使用EventStoreDB實現事件溯源的Java開源專案事件Java
- 事件溯源概念深入人心:Kafka將拋棄ZooKeeper,替換為自我管理的後設資料仲裁事件Kafka
- 為什麼放棄精準測試平臺?
- 我們為什麼需要CDP?
- 為什麼我們需要 VuexVue
- 我們為什麼要用RedisRedis
- 我們為什麼而工作
- 《後來的我們》,為什麼我們會錯過彼此?
- 如何讓客戶方便地使用事件溯源?事件溯源有什麼好處?- daryush_d事件
- 我為什麼在最後一刻放棄了近視眼手術
- 為什麼 Ubuntu 放棄 Unity?創始人如是說UbuntuUnity
- 2019 為什麼我們還會繼續使用 PHP ?PHP
- 使用AsyncAPI規範簡潔實現CQRS事件溯源案例API事件
- 因果迷境:為什麼我們會問“為什麼”?
- 當我們說開放世界的時候,我們到底在說些什麼?
- 到底為什麼我們需要 Clickhouse?