3 種 CQRS 架構模式
命令 / 查詢分離 (CQS)
1988 年,Bertrand Meyer 在面向對象的軟件設計一書中設計了 CQS 原則。簡單來說,這個原則是說程序應當要麼修改系統(Command),要麼返回查詢結果 (Query),軟件中應當保持命令與查詢的分離。
儘管 Martin Fowler 在他 2005 年的博客文章中也提到,這種分離並非總是可能的,一個很好的例子是返回一個剛插入的記錄的 id。首先,你要把記錄持久化(Command),其次,你要獲得它新分配的 id(Query)。
CQRS 架構
CQRS 建議將應用程序層分爲兩個方面,即命令端(Command)和查詢端(Query)。
查詢端負責優化讀取數據。從持久化獲取數據,然後將它們映射到展現層表單,這些表單通常被標識爲數據傳輸對象(DTO)。
命令端關注優化寫入數據。命令執行各種用例,修改實體狀態並將其持久化。
通過分離讀寫操作,我們提高了性能,並在系統中支持關注點分離原則。
本文介紹 3 種主要的 CQRS 架構實現。
單數據庫 CQRS
單一數據庫 CQRS 模式沒有正式名稱,Mattew Renze 在他的課程 Clean Architecture 中將其命名爲單一數據庫 CQRS,我也選擇這個命名。
單數據庫 CQRS
顧名思義,雙方都在和一個數據庫對話。Command 在域中執行用例,從而修改實體的狀態,然後通過 ORM 如 Entity Framework Core 或 Hibernate 將實體保存到數據庫中。
Query 直接通過數據訪問層執行,數據訪問層要麼是使用各種 ORM,要麼通過存儲過程。
雙數據庫 CQRS
在 “雙數據庫” 方式中,我們需要兩個數據庫,一個用於寫操作,一個用於讀操作。命令端使用針對寫操作優化的數據庫。查詢端使用針對讀取操作優化的數據庫。
雙數據庫 CQRS
命令每改變一個狀態,修改後的數據就必須從寫數據庫推送到讀數據庫中,或者作爲一個跨兩個數據庫的分佈式事務,或者使用最終一致性模型。
這種架構給軟件的查詢端帶來了數量級的性能提升,這是有利的,因爲一般系統在讀數據上花費的時間一般比寫數據要更多。
事件源 (Event source) CQRS
最後一種是最複雜的 CQRS 架構。與前面兩種方式相比,事件源存儲數據的思路完全不同。
在事件源方法中,我們並不只存儲實體的當前狀態,而且將實體發生的每一個狀態作爲快照來存儲。實體並不是以標準化數據的形式保存,而是通過事件的時間戳來保存它們的變更。
事件源 CQRS
事件源帶有以下好處:
-
事件存儲包括完整的審計跟蹤,可以在需要嚴格監管的場景中派上用場。
-
可以在任何時間點重建任何實體的任何狀態,這對於調試非常有用。
-
可以重放事件,查看系統中任何時候到底發生了什麼。這個功能對於壓力測試和 bug 修復非常有用。
-
可以輕鬆地重建生產數據庫。
-
有多個爲讀優化的數據存儲。
但在另一方面,這種方式實現很複雜,如果你不能從其中受益,那麼用這個模式可能適得其反。
小結
**CQRS 真正的威力在於可以對寫和讀操作進行不同的優化。**但在另一方面,系統會變得更加複雜,命令端和查詢端代碼不完全一致。並且由於存在多個數據庫,管理更復雜,需要更繁瑣的 ORM 映射。
文中鏈接:
-
clean architecture https://www.pluralsight.com/courses/clean-architecture-patterns-practices-principles
-
Command-query separation https://en.wikipedia.org/wiki/Command%E2%80%93query_separation
-
Martin Fowler’s 談 CQS https://martinfowler.com/bliki/CommandQuerySeparation.html
-
分離點關注 1 https://en.wikipedia.org/wiki/Separation_of_concerns
-
分離點關注 2 https://www.goodreads.com/quotes/tag/separation-of-concerns
-
最終一致性 https://theacetechnologist.com/post/eventually-consistent-architecture-pattern/
英文原文:
https://levelup.gitconnected.com/3-cqrs-architectures-that-every-software-architect-should-know-a7f69aae8b6c
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/XdZuCbMblTq9i4259jTswQ