1. 程式人生 > >數據庫(七),讀寫分離到CQRS

數據庫(七),讀寫分離到CQRS

變異 命令 建立 問題 來看 發布 24小時 實時更新 為什麽

讀寫分離

當一個公司業務不斷擴展,用戶量大量增加,原來使用的數據庫很可能就撐不住了。那麽可以

  • Scale-in,擴充硬件的性能,但是很可能用戶量繼續增長,增加的性能很快就吃光了。

  • 讀寫分離:數據庫撐不住了,無非就是讀寫量過大,特別是有一些復雜的查詢比如最近24小時最熱門的產品等。需要很復雜的SQL語句,運行起來當然是慢。

但是為了讀寫分離,需要把數據庫拆分為master庫和Slave庫,

市面上主要的關系數據庫都支持數據復制功能,所以可以把一個數據庫拆分為Master和Slave兩種角色,寫操作在主上,由Master服務器向其他Slave服務器進行同步。

讀操作以及數據分析等離線操作都在Slave服務器上進行。

我們知道互聯網的很多應用都是讀的,這樣有多個Slave可以負載分擔一下,又可以保證數據的可用性和正確性。

技術分享圖片

但是相應的原有的應用代碼也需要修改,必須改為寫數據用master庫,讀數據的時候使用slave庫,就相當於重寫了。

復雜查詢

但是就算重寫了代碼,發現性能還是無法得到明顯的提升,原因仍然是使用了太多復雜的查詢,比如說有很多表在聯接,在數據庫(四),數據庫組成部分裏面我們都說過,聯接非常消耗性能。

那麽我們可不可以單獨用一張表來存放過去24小時的熱門產品啊,這樣只需要使用簡單的SQL就能搞定。

也就是說,一套單一的數據庫表對報表、搜索、事務等不同的行為是不適當的。

現在的表是為了新增、修改數據

而設計的,對復雜查詢不適合。

但是我們還需要考慮這個查詢庫如何更新的問題,還就是可能不是實時更新,我們能否忍受這種延遲的問題。

CQRS

能否忍受延遲的問題需要從業務上來看,比如過去24小時熱門的極品,一點點過時的信息沒有太大的影響,只要求最終一致即可。

我們可以使用CQRS(Command Query Responsibility Segregation),也就是增刪改的命令與查詢責任分離
技術分享圖片

在CQRS中,強調的是讀(Query)寫(Command)分離,因為用戶讀到的數據通常是過時的,那麽為什麽還需要從數據庫讀一遍呢,可以直接建立一個讀數據源。可以是Cache,可以是XML、JSON等。

那之前提到的怎麽更新的問題怎麽解決?可以使用Event,也就是事件,比如某個產品賣出去了,可以發布一個事件,修改原有的Read Model。

這樣就通過事件機制把同步變成了異步。

最後,這種方法最好只在復雜查詢中用,原來的簡單查詢依然在關系型數據庫裏面取。為什麽呢?因為引入一種新的技術需要付出代價,比如同步變異步了,還需要事件機制,我們不能只看到新技術的優點,而看不到缺點了。

技術分享圖片

主要參考

從讀寫分離到CQRS,張大胖是如何解決性能問題的?

數據庫(七),讀寫分離到CQRS