分庫分表基礎
資料庫容器成為後端的瓶頸,可以通過增設緩存、讀寫分離、優化索引和SQL等方式減小資料庫的壓力。如果這些方法並不奏效,那麼可以考慮分庫分表。
- 垂直分表:大表拆成若干個小表(每個表欄位不同)
- 垂直分庫:一個庫中的表,分到若干個庫中
- 水平分表:也叫橫向分表,把一個庫中的表,分為到若干表中(每個表欄位相同)。使用hash和mod,分到不同表中。
- 水平分庫分表:把一個庫中的表分到不同庫的相同表中(每個表欄位相同)
分庫分錶帶來的問題是:跨庫join,出於性能和安全性的考慮,這種做法一般是禁止的。
常見的拆分策略有哪些呢?
1)查詢切分:將ID和庫的Mapping關係記錄在一個單獨的庫中
優點:ID和庫的Mapping演算法可以隨意更改。
缺點:引入額外的單點。
2)範圍切分:按照時間區間或ID區間來切分。
優點:單表大小可控,天然水平擴展。
缺點:無法解決集中寫入瓶頸的問題。
3)Hash切分:Hash和Mod
以統一訂單庫為例,分庫分表的方案可以是32*32的,即通過UserId後四位mod 32分到32個庫中,同時再將UserId後四位Div 32 Mod 32將每個庫分為32個表,共計分為1024張表。線上部署情況為8個集群(主從),每個集群4個庫。
2018-01-02閱:
關於資料庫,可以想像成一個現實中的實物倉庫,其功能是實物的快速存取。隨著貨物和存取的增加,通常會遇到兩個問題:
- 貨物太多,倉庫存放不下
- 貨物太多,訪問頻繁,導致IO很慢。
所謂的索引、SQL、讀寫分離,不能完全解決上述問題。
一個優化方案是拆掉這個倉庫,重建一個大倉庫,這種方案極其錯誤:
- 單機容量是有限的
- 不易擴展,無法滿足數據的激增
- 大量數據存在一個庫中,導致IO更慢
我們可以新建N個倉庫,把不同業務的貨物分配到不同的倉庫中。這就是資料庫的垂直拆分,優點是貨物的存放更有條理,能減輕IO壓力。缺點是要配置多個數據源,而且跨庫的事務和級聯都變得非常複雜。
垂直拆分以後,倉庫A存在業務A的貨物,但是由於業務A的貨物非常大,是的倉庫A還是覺得業務很大,所以得把貨物分到其他倉庫中,這就是資料庫的水平拆分。這麼做的好處是顯而易見的,但也帶了一些問題:
- 服務層不知道業務A的數據存放在哪一個庫中,所以需要SQL路由。
- 不同庫的相同表中,主鍵的生成不能依賴Oracle的sequence或者MySQL的自增欄位。
- 查詢數據要查詢多個庫,而且數據量很大時,需要分頁查詢,這會非常複雜。
說了這麼多,似乎可以從資料庫窺見一些計算機存儲的奧秘:
不管是什麼層次的存儲器,容量都是有限的,而數據可以無限增長,所以保持存儲高效的不二法門就是不讓存儲器存放過多的數據。雖然看起來是句廢話,但卻是頂層設計的圭臬。
參考資料:
分庫分表的幾種常見形式以及可能遇到的難
大眾點評訂單系統分庫分表實踐 -
《大型網路系統與Java中間件實踐》
推薦閱讀:
※什麼鬼!基於備份恢復的數據還能變多?
※【案例分享】SequoiaDB+Spark搭建醫院臨床知識庫系統
※循序漸進學習如何在 MariaDB 中配置主從複製
TAG:資料庫 |