結合業務深入研究分庫分表方案-理論篇

問題描述

對於一個大型的互聯網應用,海量數據的存儲和訪問成爲了系統設計的瓶頸問題,對於系統的穩定性和擴展性造成了極大的問題。通過數據切分來提高網站性能,橫向擴展數據層已經成爲架構研發人員首選的方式。

•水平切分數據庫:可以降低單臺機器的負載,同時最大限度的降低了宕機造成的損失;

•負載均衡策略:可以降低單臺機器的訪問負載,降低宕機的可能性;

•集羣方案:解決了數據庫宕機帶來的單點數據庫不能訪問的問題;

•讀寫分離策略:最大限度了提高了應用中讀取數據的速度和併發量;

1、單個表數據量越大,讀寫鎖,插入操作重新建立索引效率越低。

2、單個庫數據量太大(一個數據庫數據量到1T-2T就是極限)

3、單個數據庫服務器壓力過大

4、讀寫速度遇到瓶頸(併發量幾百)

解決問題的思路:根據自己的實際情況,當單表過大的時候進行分表,數據庫過大的時候進行分庫,高併發的情況考慮讀寫分離和集羣。

數據拆分的方式有:分區、分表、分庫

•分區

•就是把一張表的數據分成N個區塊,在邏輯上看最終只是一張表,但底層是由N個物理區塊組成的

•分表

•就是把一張表按一定的規則分解成N個具有獨立存儲空間的實體表。系統讀寫時需要根據定義好的規則得到對應的字表明,然後操作它。

•分庫

一旦分表,一個庫中的表會越來越多

將整個數據庫比作圖書館,一張表就是一本書。當要在一本書中查找某項內容時,如果不分章節,查找的效率將會下降。而同理,在數據庫中就是分區。

分區

什麼時候考慮使用分區?

•一張表的查詢速度已經慢到影響使用的時候。

•sql經過優化

•數據量大

•表中的數據是分段的

•對數據的操作往往只涉及一部分數據,而不是所有的數據

分區解決的問題

•主要可以提升查詢效率

分表

什麼時候考慮分表?

•一張表的查詢速度已經慢到影響使用的時候。

•sql經過優化

•數據量大

•當頻繁插入或者聯合查詢時,速度變慢

分表解決的問題

•分表後,單表的併發能力提高了,磁盤I/O性能也提高了,寫操作效率提高了

•查詢一次的時間短了

•數據分佈在不同的文件,磁盤I/O性能提高

•讀寫鎖影響的數據量變小

•插入數據庫需要重新建立索引的數據減少

分區和分表的區別與聯繫

•分區和分表的目的都是減少數據庫的負擔,提高表的增刪改查效率。

•分區只是一張表中的數據的存儲位置發生改變,分表是將一張表分成多張表。

•當訪問量大,且表數據比較大時,兩種方式可以互相配合使用。

•當訪問量不大,但表數據比較多時,可以只進行分區。

常見分區分表的規則策略(類似)

•Range(範圍)

•Hash(哈希)

•按照時間拆分

•Hash之後按照分表個數取模

•在認證庫中保存數據庫配置,就是建立一個DB,這個DB單獨保存user_id到DB的映射關係

分庫

什麼時候考慮使用分庫?

•單臺DB的存儲空間不夠

•隨着查詢量的增加單臺數據庫服務器已經沒辦法支撐

分庫解決的問題

•其主要目的是爲突破單節點數據庫服務器的 I/O 能力限制,解決數據庫擴展性問題。 

垂直拆分

•將系統中不存在關聯關係或者需要join的表可以放在不同的數據庫不同的服務器中。

•按照業務垂直劃分。比如:可以按照業務分爲資金、會員、訂單三個數據庫。

•需要解決的問題:跨數據庫的事務、jion查詢等問題。

水平拆分

•例如,大部分的站點。數據都是和用戶有關,那麼可以根據用戶,將數據按照用戶水平拆分。

•按照規則劃分,一般水平分庫是在垂直分庫之後的。比如每天處理的訂單數量是海量的,可以按照一定的規則水平劃分。需要解決的問題:數據路由、組裝。

讀寫分離

•對於時效性不高的數據,可以通過讀寫分離緩解數據庫壓力。需要解決的問題:在業務上區分哪些業務上是允許一定時間延遲的,以及數據同步問題。

思路:

垂直分庫-->水平分庫-->讀寫分離

數據拆分以後面臨的問題

問題

•事務的支持,分庫分表,就變成了分佈式事務

•join時跨庫,跨表的問題

•分庫分表,讀寫分離使用了分佈式,分佈式爲了保證強一致性,必然帶來延遲,導致性能降低,系統的複雜度變高。

常用的解決方案:

•對於不同的方式之間沒有嚴格的界限,特點不同,側重點不同。需要根據實際情況,結合每種方式的特點來進行處理。

•選用第三方的數據庫中間件(Atlas,Mycat,TDDL,DRDS),同時業務系統需要配合數據存儲的升級。

數據存儲的演進

單庫單表

•單庫單表是最常見的數據庫設計,例如,有一張用戶(user)表放在數據庫db中,所有的用戶都可以在db庫中的user表中查到。

單庫多表

•隨着用戶數量的增加,user表的數據量會越來越大,當數據量達到一定程度的時候對user表的查詢會漸漸的變慢,從而影響整個DB的性能。如果使用mysql, 還有一個更嚴重的問題是,當需要添加一列的時候,mysql會鎖表,期間所有的讀寫操作只能等待。

•可以通過某種方式將user進行水平的切分,產生兩個表結構完全一樣的user_0000,user_0001等表,user_0000 + user_0001 + …的數據剛好是一份完整的數據。

多庫多表

隨着數據量增加也許單臺DB的存儲空間不夠,隨着查詢量的增加單臺數據庫服務器已經沒辦法支撐。這個時候可以再對數據庫進行水平拆分。

總結

總的來說,優先考慮分區。當分區不能滿足需求時,開始考慮分表,合理的分表對效率的提升會優於分區。

垂直分庫-->水平分庫-->讀寫分離


 

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