數據庫分庫分表方案

數據庫的拆分方式有兩種:水平拆分和垂直拆分。水平拆分關注的單表數據量過大的問題,對於上千萬過億行數據的表來說,單表數據量過大,查詢和變更的成本會變大,同時單庫的吞吐量也會達到瓶頸,會同時對業務造成影響。水平拆分的目的就是爲了將單表拆分爲多表,每個表仍包含原有的數據結構。而垂直拆分關注的是表結構的拆分,我們需要根據業務的維度,將原本一個表拆分爲多個表,其中每個表的結構與原表不同,這樣不同的業務就可以根據需要訪問不同的表,提高查詢和修改的效率,當然,這同時也會帶來一些問題,就是分佈式事務的問題,這個問題我們在後面詳細討論。

根據如何切片,分庫分表的方案一般分爲三大類:客戶端分片、代理分片以及支持事務的分佈式數據庫。下面我們來分別討論:

(1)客戶端分片

就數據庫分片邏輯來說,方法其實很簡單,我們利用分表鍵的值進行hash分片,也可以根據分表鍵進行範圍分片(例如根據天來劃分,其實就是將一天的數據劃分到單張表中),還有很多其他定製的分片方法等。對數據庫分片其實很簡單,問題核心在於我們應用如何訪問分庫分表以後的數據,也就是分庫分表後的路由規則。而客戶端分片的方式是在應用層直接操作分片邏輯,每個應用都嵌入一個操作分片的邏輯實現,一般是通過jar依賴,業務在使用的時候直接依賴我們提供的jar包即可,在jar中我們提供跟基本操作數據庫一樣的操作方法,讓業務對底層分庫分表的路由和數據聚合無感知。

具體實施方式有三種:應用層直接實現,定製jdbc以及定製orm框架:

a、應用層直接實現

        改方法在應用層直接讀取分片規則,然後解析規則,根據分片規則找到路由邏輯,應用層在每次操作的時候都知道要連接哪個數據庫,以及那些表等,而我公司就是採用這種方法,改方法實現起來簡單,可以快速上線應用,而且分片邏輯自己維護,出現問題也便於快速定位和解決。給個具體的例子如下: 

如圖所示,業務應用在鏈接數據庫的時候,首先會向規則服務器發起請求,找到其目標數據庫的路由規則,然後通過該路由規則分別連上分片的DB,在獲得數據後在應用內部進行數據聚合並返回給應用接口。當然這裏路由規則可以使用本地緩存,不然每次連接都發起請求會造成規則服務器壓力增大,同時也會增大應用跟數據庫的交互時間,影響用戶體驗。但是,當分庫分表的路由規則發生變化的時候怎麼辦呢?我就希望規則服務器可以將變更的信息推送到我們應用,讓應用更新本地緩存。當然,這樣又會讓我們覺得我們對應用有了侵入,所以,我們公司在做規則保存和動態便跟的時候專門開發了一款動態配置信息變更的應用。後來該應用不僅用來做數據庫分庫分表規則的動態配置,後續很多的應用也在使用,後面我們再詳細介紹。

b、通過定製jdbc協議

我們同樣可以通過定製jdbc協議來實現我們的需求,讓分庫分表的邏輯在jdbc內部實現。這種方式雖然不對業務入侵,但是開發者必須要理解jdbc協議才能實現分庫分表邏輯,sharding jdbc就是採用這種方式。

c、通過定製orm框架實現

我們也可以通過定製orm框架,將分片規則實現到orm中,可以通過在mybatis配置文件的sql中增加表索引參數來實現,單是改方式不夠系統化,同時要求業務方自己配置,後續很難管理,除了問題很難排查。

(2)代理分片

代理分片很好理解,就是我們再應用和DB之間加一層代理,分片路由規則放在代理,有代理幫助我們去做路由和數據聚合。但是這種方式是增加了代理,會對性能有影響,畢竟中間加了一層網絡傳輸,同時,我們還需要維護一套代理服務器,增加了成本,而且還要保證代理服務的可以,也會增加成本和開發運維的難度。

(3)支持事務的分佈式數據庫

這個就牛逼了,阿里的OceanBase就是支持分佈式事務的數據庫,其內部完全對使用者透明,用戶完全不用關心起內部如何彈性伸縮,如何實現分佈式事務,用就好了。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章