使用Kafka Streams構建事件源系統的經驗
在基輔召開的JEEConf會議上,Amitay Horwitz描述了他和他的團隊如何實施事件溯源的發票系統,他們在生產2年半後遇到的挑戰以及他們如何使用Kafka Streams實施新設計。
Wix的軟體工程師Horwitz 於2015年開始與他的團隊一起開展新的發票服務,目的是幫助他們的客戶管理發票並線上接收付款。在設計新服務時,他們希望建立一個小而簡單的庫,該庫非侵入式,維護資料完整性,並且能夠輕鬆新增自定義檢視。為了實現所有目標,他們決定使用事件源架構來實現服務。
他們也遇到了問題,客戶有時無法看到新建立的發票,因為從寫入到讀取是最終一致性。
但他們最大的問題是重建檢視。確保在沒有事件進入的情況下觸發重建,事實證明它比預期的更復雜,特別是在具有來自各種伺服器的事件的分散式環境中。這些問題使Horwitz尋求替代架構,同時保持事件溯源的好處。
Horwitz將Kafka描述為一個複製的,容錯的,分散式附加日誌。它通常用於pub-sub或佇列,但他指出它可以做更多。Kafka中的基本結構是一個分割槽的主題,一個邏輯佇列。生產者將根據訊息中的key將訊息推送到每個分割槽,然後消費者可以使用這些訊息。對於事件源系統至關重要的兩個重要特性是在單個分割槽內維護訊息之間的排序,並且訊息即使在消耗之後也可以儲存。
Kafka Streams將流處理帶給了Kafka。它有兩個主要的抽象:
1. Horwitz認為流中的資料流是一種無限有序和可重放的不可變資料序列,這使得它對於事件源系統來說很有趣。保證了順序。
2. 能在靜態資料中看到Table,表Table儲存聚合資料的某個時間點狀態檢視,該檢視在接收到新訊息時更新。
在使用Kafka的發票服務的新設計中,有一個快照狀態儲存,用於儲存每個聚合的當前狀態,從命令流接收命令後,命令處理程式Handler會根據聚合ID從快照狀態儲存中讀取相應聚合的當前狀態;然後,該處理程式Handler確定命令是成功被執行還是失敗了,並透過結果流返回結果;如果命令執行成功,則會建立事件並將其傳送到事件儲存庫;接下來,讀取這邊系統查詢有新事件的流,並將狀態儲存中的聚合更新為其新狀態(banq注:注意更新狀態在讀取這邊,不是寫入那邊),他指出,命令處理程式Hanlder邏輯可以用非常簡潔和宣告的方式編寫,在他的示例中只有60行Scala程式碼。
在新的架構中,Kafka位於中心,微服務與Kafka通訊,彼此之間也透過Kafka進行通訊。他們還可以在建立分析報告時將資訊推送到Kafka或提取資訊,總之,Horwitz指出,新設計給了他們幾個優勢:
1. 一個簡單的宣告式系統
2. 最終的一致性現在已被接受並優雅地處理
3. 新增或更改檢視很容易
4. 使用Kafka提高了可擴充套件性和容錯能力
新設計仍處於評估階段,儘管他們在生產中大量使用卡夫卡。他指出,有人聲稱Kafka不適合CQRS或事件來源系統,但他認為,如果能進行權衡,Kafka可以被利用。如果使用不同的客戶端屬性儲存頁面檢視事件,就可以根據該事件資訊輕鬆建立聚合,這是一種事件溯源形式,他認為Kafka非常適合。
透過使用聚合的標識作為Kafka的分割槽鍵key,同一聚合的所有命令將最終位於命令主題的同一分割槽中,並將在單個執行緒中(單寫)按順序處理。這樣,在前一個生成所有下游事件之前不會處理任何命令,並且Horwitz指出這將建立強大的一致性保證。
https://www.infoq.com/news/2018/07/event-sourcing-kafka-streams
Wix的軟體工程師Horwitz 於2015年開始與他的團隊一起開展新的發票服務,目的是幫助他們的客戶管理發票並線上接收付款。在設計新服務時,他們希望建立一個小而簡單的庫,該庫非侵入式,維護資料完整性,並且能夠輕鬆新增自定義檢視。為了實現所有目標,他們決定使用事件源架構來實現服務。
他們也遇到了問題,客戶有時無法看到新建立的發票,因為從寫入到讀取是最終一致性。
但他們最大的問題是重建檢視。確保在沒有事件進入的情況下觸發重建,事實證明它比預期的更復雜,特別是在具有來自各種伺服器的事件的分散式環境中。這些問題使Horwitz尋求替代架構,同時保持事件溯源的好處。
Horwitz將Kafka描述為一個複製的,容錯的,分散式附加日誌。它通常用於pub-sub或佇列,但他指出它可以做更多。Kafka中的基本結構是一個分割槽的主題,一個邏輯佇列。生產者將根據訊息中的key將訊息推送到每個分割槽,然後消費者可以使用這些訊息。對於事件源系統至關重要的兩個重要特性是在單個分割槽內維護訊息之間的排序,並且訊息即使在消耗之後也可以儲存。
Kafka Streams將流處理帶給了Kafka。它有兩個主要的抽象:
1. Horwitz認為流中的資料流是一種無限有序和可重放的不可變資料序列,這使得它對於事件源系統來說很有趣。保證了順序。
2. 能在靜態資料中看到Table,表Table儲存聚合資料的某個時間點狀態檢視,該檢視在接收到新訊息時更新。
在使用Kafka的發票服務的新設計中,有一個快照狀態儲存,用於儲存每個聚合的當前狀態,從命令流接收命令後,命令處理程式Handler會根據聚合ID從快照狀態儲存中讀取相應聚合的當前狀態;然後,該處理程式Handler確定命令是成功被執行還是失敗了,並透過結果流返回結果;如果命令執行成功,則會建立事件並將其傳送到事件儲存庫;接下來,讀取這邊系統查詢有新事件的流,並將狀態儲存中的聚合更新為其新狀態(banq注:注意更新狀態在讀取這邊,不是寫入那邊),他指出,命令處理程式Hanlder邏輯可以用非常簡潔和宣告的方式編寫,在他的示例中只有60行Scala程式碼。
在新的架構中,Kafka位於中心,微服務與Kafka通訊,彼此之間也透過Kafka進行通訊。他們還可以在建立分析報告時將資訊推送到Kafka或提取資訊,總之,Horwitz指出,新設計給了他們幾個優勢:
1. 一個簡單的宣告式系統
2. 最終的一致性現在已被接受並優雅地處理
3. 新增或更改檢視很容易
4. 使用Kafka提高了可擴充套件性和容錯能力
新設計仍處於評估階段,儘管他們在生產中大量使用卡夫卡。他指出,有人聲稱Kafka不適合CQRS或事件來源系統,但他認為,如果能進行權衡,Kafka可以被利用。如果使用不同的客戶端屬性儲存頁面檢視事件,就可以根據該事件資訊輕鬆建立聚合,這是一種事件溯源形式,他認為Kafka非常適合。
透過使用聚合的標識作為Kafka的分割槽鍵key,同一聚合的所有命令將最終位於命令主題的同一分割槽中,並將在單個執行緒中(單寫)按順序處理。這樣,在前一個生成所有下游事件之前不會處理任何命令,並且Horwitz指出這將建立強大的一致性保證。
https://www.infoq.com/news/2018/07/event-sourcing-kafka-streams
相關文章
- 經驗分享:從CRUD重構到事件源ES的有狀態系統 -Stitcher.io事件
- IBM 使用 react 構建的開源設計系統IBMReact
- 使用Kafka和Flink構建實時資料處理系統Kafka
- 為什麼我們放棄使用Kafka Streams實現全部的事件溯源?-MateuszKafka事件
- 使用Java和Reactive Streams構建流式應用JavaReact
- 經驗分享:RabbitMQ與Kafka等訊息系統的使用者討論 - ycombinatorMQKafka
- DoorDash使用 Kafka 和 Flink 構建可擴充套件的實時事件處理Kafka套件事件
- Halodoc使用 Apache Hudi 構建 Lakehouse的關鍵經驗Apache
- 經驗教訓帖:探尋Reddit廣告服務系統的構建!
- 使用Spring Boot和Kafka Streams實現CQRSSpring BootKafka
- 使用開源元件構建自動運維Kafka叢集 - Slack元件運維Kafka
- Slack使用開源元件構建自動驅動Kafka叢集元件Kafka
- 網易基於 Iceberg 的實時湖倉一體系統構建經驗
- Kafka入門(構建TB級非同步訊息系統)及Spring整合KafkaKafka非同步Spring
- Azkarra Streams簡介:Apache Kafka Streams的第一個微框架ApacheKafka框架
- 使用LangGraph構建多Agent系統架構!架構
- 從0到1搞懂分散式架構:Uber大型支付系統構建經驗總結分散式架構
- Laravel事件系統的使用Laravel事件
- Kafka Streams+SpringBoot之探索:統計計數 - mydeveloperplanetKafkaSpring BootDeveloper
- 如何在一週內使用Kafka+Redis構建分散式排行榜系統? - AritraKafkaRedis分散式
- 優步分享基於Apache Kafka的Presto使用經驗ApacheKafkaREST
- 使用Kafka重新架構電子商務系統 - DinaKafka架構
- 使用 Proxy 構建響應式系統
- DoorDash如何使用 Apache Kafka 和 Elasticsearch 構建更快的索引?ApacheKafkaElasticsearch索引
- Kafka Streams開發入門(1)Kafka
- 常用快取系統使用經驗總結快取
- 如何使用NodeJS構建基於RPC的API系統NodeJSRPCAPI
- 智慧金融系統的構建
- 經驗分享:我們如何使用AWS構建無伺服器架構 - hypertrack伺服器架構
- 使用Kafka Streams和Spring Boot微服務中的分散式事務 - PiotrKafkaSpring Boot微服務分散式
- 使用Kafka實現事件溯源Kafka事件
- 實戰經驗分享:使用 PyO3 來構建你的 Python 模組Python
- `centos7`系統構建本地yum源並配置共享CentOS
- 「譯」如何使用 NodeJS 構建基於 RPC 的 API 系統NodeJSRPCAPI
- 系統設計:使用Scala、Spark和Hadoop構建推薦系統SparkHadoop
- [譯] 使用原生 JavaScript 構建狀態管理系統JavaScript
- [譯] 使用 Go 和 ReactJS 構建聊天系統 (四)GoReactJS
- [譯] 使用 Go 和 ReactJS 構建聊天系統 (三)GoReactJS