CQRS 是一種 微服務 架構模式 ,它代表命令和查詢責任分離。
這種模式背后的基本思想是將寫操作與讀操作分開。不是使用一個數據存儲來執行 CRUD 操作,而是在一個數據存儲上執行讀取操作,并在不同的數據存儲上執行創建/更新。
CQRS 承諾對大規模應用程序的穩定性和可 擴展性 以及顯著的性能改進。
CQRS 模式由 Bertrand Meyer 設計,作為開發 Eiffel 編程語言的一部分。Greg Young 創造了“CQRS”一詞。
CQRS 在哪里使用?
CQRS 通常在準備就緒的大規模分布式應用程序中是首選。也就是說,如果應用程序中的讀取次數遠遠超過寫入操作的次數。
此模式的另一個合適用例是讀取操作繁重且數據存儲副本可以放置在應用程序接收高流量的地理位置附近,從而提高數據庫讀取操作的性能。
CQRS 是如何實現的?
到目前為止,我們知道要實現 CQRS ,我們將使用兩個數據存儲庫。
通常,寫入操作首選關系數據庫,其中可以應用所有數據約束,并使用NoSQL 數據庫支持讀取操作。這意味著,兩種不同的數據模型用于寫入和讀取操作。
自然,人們會想到的問題是這兩個存儲庫中的數據如何同步?
這就是事件驅動 架構 出現的地方。
考慮一個用戶調用POST API的場景,執行一些驗證,然后將數據及其約束更新到我們的關系數據庫中。
將數據插入數據庫后,將調用觸發器,該觸發器將更新所有事件處理程序(事件驅動架構)以更新讀取的數據庫。
當另一個用戶調用 GET API 時,應用程序將從NoSQL 數據庫中檢索相關數據并將其發送回用戶。用于實現 CQRS 的最流行的基于 JAVA 的框架是 Axon。
Axon 使用命令和處理程序來調用和處理相應的事件。 你可以在Github 上找到完整的代碼。
使用 CQRS 有什么好處?
使用 CQRS 的主要好處包括:
靈活的擴展——讀寫數據存儲可以根據需求獨立擴展。 簡單查詢——由于讀取和寫入的數據模型是分開的,讀取數據模型可以設計成避免復雜查詢的方式。 提高性能——通過優化讀取操作并將數據存儲副本放置在不同的地理位置,讀取繁重的操作可以顯著提高性能。使用 CQRS 的缺點是什么?
復雜性——事件驅動的系統構建和維護起來很復雜。盡管有像 Axon 這樣的框架可以處理數據庫寫入、發布事件和通知各種處理程序,但也有讀寫模型不同步的情況。 一致性——CQRS 和事件驅動架構旨在確保數據在所有涉及的系統中保持一致,但在消息失敗的情況下,讀取數據庫將不同步。結論
在讀取次數遠大于寫入次數的情況下,CQRS 是一種需要考慮的模式。特別是在讀取操作要高度優化并且不需要執行任何業務邏輯或驗證的情況下。讀取操作就像獲取數據、加載 DTO 并將其傳遞給客戶端一樣簡單。
實現這樣一個系統的最大挑戰是確保避免數據重復,讀取數據庫永遠不會過時,并且寫入數據庫的所有條目最終也會在讀取數據庫中一致地更新。
盡管從概念上講,這聽起來很簡單,但 CQRS 并不那么容易實現和調試。