一步步帶你了解分布式資料庫的架構演變之路!

2022-02-26 01:15:51 字數 4276 閱讀 7812

mycat 是乙個資料庫分庫分表中介軟體,使用 mycat 可以非常方便地實現資料庫的分庫分表查詢,並且減少專案中的業務**。今天我們將通過資料庫架構發展的演變來介紹 mycat 的誕生背景,以及 mycat 在其中扮演的角色,從而使得大家對 mycat 的誕生及其作用有深入的理解。

1單資料庫架構

乙個專案在初期的時候,為了盡可能快地驗證市場,其對業務系統的最大要求是快速實現。在這個階段,**開發人員為了能快速實現業務系統,一般都是將所有層級(mvc)的業務**都寫在同乙個專案中,所有的業務資料都存放在同乙個資料庫中。此時,專案的整體架構圖如下所示:

單資料庫架構

從上圖可以看到,我們在乙個專案中集中了註冊、登陸、購物三個模組的業務**,並且這三個業務模組都讀取同乙個業務資料庫。

但隨著專案的不斷推進,使用者量不斷增長,單台應用伺服器已經無法承受如此巨大的流量了。此時常見的做法是把專案進行分布式部署,分散單台伺服器的流量,從而可以暫時緩解使用者增長帶來的應用伺服器壓力。此時的專案架構圖如下所示:

分布式部署-單資料庫架構

但隨著我們部署的應用伺服器越來越多,後端的單台資料庫伺服器已經無法承受如此巨大的流量了。為了盡快緩解使用者訪問壓力,我們一般是在應用伺服器與資料庫伺服器中間加多乙個快取層,通過快取可以抵消掉一部分的資料庫查詢操作。此時的專案架構圖如下所示:

分布式部署-快取-單資料庫架構

但是增加資料庫快取層只能緩解資料庫訪問壓力,攔截部分資料庫訪問請求。隨著使用者訪問量的進一步增長,資料庫訪問的瓶頸還是會進一步凸顯。這個時候,我們不得不對資料層的架構進行改造。

2主從資料庫架構

這個時候常用的解決方案就是將原本單台資料庫伺服器變成主從模式的資料庫伺服器,即一台資料庫作為主庫支援寫入資料,一台資料庫作為讀庫支援查詢資料。此時專案的架構圖如下所示:

主從資料庫架構

我們通過資料庫主從同步實現了讀寫分離,將所有讀操作都引導到從庫進行,將所有寫操作都引導到主庫進行。

因為我們對資料庫層進行了改造,規定所有讀資料庫操作要訪問從庫,所有寫資料庫操作要訪問主庫,那麼我們就必須對原來的**進行改造。

public user selectuser()

public user insertuser()

上面是改造前的**,無論是讀操作還是寫操作,我們都使用同乙個資料來源進行操作。但為了適應新的資料庫架構,我們必須在**中手動判斷應該請求哪個資料來源。

public user selectuser()

public user insertuser()

經過修改後的**,開發根據自身經驗判斷應該選擇哪個資料來源進行操作。當是讀操作的時候,我們選擇 readtemplate。當是寫操作的時候,我們選擇 writetemplate。

但作為乙個程式設計師,我們隱隱約約覺得識別應該用哪個資料來源這個判斷不應該人工判斷,而應該自動讓**去判斷。畢竟這個判斷的模式很簡單 —— 如果是 select 那麼就用讀的資料來源,如果是其他那麼就用寫的資料來源。

其實這個就是 mycat 的用途之一,即作為乙個資料庫中介軟體去解決資料來源判斷問題。如果我們使用 mycat 作為資料庫中介軟體,那麼我們不需要關心我應該使用哪個資料來源。mycat 幫我們遮蔽了不同資料來源的差異,對於我們來說就只有乙個資料來源,這個資料來源能處理寫操作,也能處理讀操作。上面查詢和插入的**就可以變成下面這樣:

public user selectuser()

public user insertuser()

實現了主從資料庫架構,再使用 mycat,你發現我們並不需要去修改太多的**,只需要將資料來源改為 mycat 位址即可。mycat 自動把我們所有的語句傳送給後端的 mysql 伺服器。

上面說的這些問題只是實戰中遇到的一部分問題,事實上遇到的問題只會更多不會更少,而且隨著業務的不斷發展會愈加凸顯。

3垂直切分資料庫架構

此時為了各個業務模組不互相影響,我們把應用層進行垂直拆分,即把註冊模組、登陸模組、購物模組都單獨作為乙個應用系統,分別讀寫獨立的資料庫伺服器。此時,我們的系統架構圖如下圖所示:

垂直切分資料庫架構

實現了垂直拆分之後,我們可以成功解決上面說到的三個問題:業務模組相互影響問題、單資料庫壓力問題。

但是隨著業務的進一步擴大,我們又增加了許多業務模組:客服模組、錢包模組、個人中心模組、收藏夾模組、訂單模組等。按照我們之前所設計的資料庫架構,我們會存在許多個資料來源,這些資料來源分散在各個專案中:

對於乙個專案管理者來說,這麼多的資料來源分散在不同專案中,怎麼統一管理是乙個問題。很多時候我們都很難記住這個專案連線的是哪個資料庫,那個專案連線的是哪個資料庫。

但如果你使用了 mycat 作為資料庫中介軟體的話,mycat 就可以幫你解決這個問題。對於所有專案來說,它們只需要統一連線 mycat 對外提供的乙個位址,而 mycat 則幫這些專案聯絡所有後端的 mysql 資料庫。對於前端的專案倆說,它們只知道 mycat 這個資料庫中介軟體,而不需要去理會我到底連線哪個資料庫,mycat 通過自身配置可以完成這個任務。

哪個表的冗餘**,從而讓開發人員更專注於業務邏輯的開發。

4水平切分資料庫架構

當資料庫架構經歷了主從架構、垂直拆分架構之後,應對一般的業務讀寫是沒有什麼問題了。但對於一些核心的業務資料,可能還是會有瓶頸問題,例如使用者模組。

對於一些使用者量高達乙個億的使用者系統來說,即使經過主從架構、垂直拆分架構的優化,但其使用者資料庫的單個表裡需要儲存的資料還是高達乙個億的大小。如果我們把所有的資料都存放在乙個表裡,無論是註冊時的插入資料,或者是登陸時的查詢資料,勢必會變得很慢。

這時候,我們就不得不對這些高資料量的核心業務表進行水平拆分,即將海量的資料記錄拆分到多張表中儲存。例如我們一開始可能只有一張 user 表,我們將 user 表按照使用者 id 對 1000 取餘進行拆分,那麼我們就會有 1000 張表,分別是 user_000 至 user_999。此時,專案的架構圖如下所示:

水平切分資料庫架構

當我們在**中查詢使用者資料時,我們先根據使用者 id 取餘判斷其應該操作的表,之後再查詢對應的表。例如 userid 為 90749738 的使用者就應該查詢 user_38 表,userid 為 74847383 的使用者就應該查詢 user_83 表。

通過水平拆分,我們成功解決了海量資料核心業務表的讀寫瓶頸問題。但此時在**層面上有乙個問題出現了,那就是我們需要在查詢資料庫之前,根據 userid 去判斷應該查詢哪個表,這個操作對於所有業務模組來說都是高度一致的,應該抽離成乙個公用的專案。

與判斷應該使用讀資料來源還是寫資料來源一致,我們都覺得這樣機械的任務不應該丟給程式設計師做,應該讓機器去做。這其實就是 mycat 可以幫我們做的事情:mycat 通過配置一系列的分庫分表規則,讓 mycat 幫我們自動判斷應該查詢哪乙個分表。通過使用 mycat 資料庫中介軟體,我們可以省去在**層判斷查詢哪個表的冗餘**,從而讓開發人員更專注於業務邏輯的開發。

5總結

從單一的資料庫架構,到主從讀寫分離的資料庫架構,再到垂直拆分、水平拆分的資料庫架構。我們可以看到 mycat 幫我們解決了讀寫資料來源判斷、繁雜資料源位址、分表判斷這三個機械的重複性的問題

但 mycat 發展至今,其功能已經遠遠超過上面說的這三個。例如 mycat 支援主從切換功能,當資料庫主庫發生網路問題或其他故障時,mycat 可以自動切換到從庫,從而保證正常讀寫功能的進行。mycat 的定位是乙個資料庫中介軟體,但凡所有處於應用層和資料層之間的事情,mycat 都可以做。

通過這篇文章,我們了解了 mycat 的誕生背景以及其最基本的作用。

帶你一步步了解業務測打款系統的建立

初始階段 業務方訂單審核通過後,會有離線任務不斷輪訓向支付中心發起呼叫,支付中心打款處理完成後會返回ifsuccess 是否落庫 state,code,error message等。如果落庫且code為打款成功,訂單業務狀態會修改為打款成功。發展階段 為了配合業務發展,會增加各種活動來拉動訂單量,有...

初步了解分布式資料庫HBase

hbase是乙個高可靠 高效能 面向列 可伸縮的分布式資料庫,它是谷歌bigtable的開源實現,主要用來儲存非結構化和半結構化的鬆散資料。hbase的目標是處理非常龐大的表,可以通過水平拓展的方式,利用廉價計算機集群處理超過10億行資料和數百萬列元素組成的資料表。hbase利用 hadoop ma...

資料結構與演算法第 4 講 一步步帶你手寫鍊錶

前面我們講過,鍊錶是一種很好的資料儲存方式,對於資料的插入和刪除效率都很高,一般我們常用的是jdk裡的鍊錶,很多人用的雖多,卻不一定都熟悉具體的寫法和邏輯,而且jdk為了相容性更好,難免在效率上進行妥協,如果你對效能有很高的要求,不妨根據自己的需求去手動實現乙個鍊錶。第一步 首先建立乙個節點內部類 ...