標籤:

分庫分表基礎

資料庫容器成為後端的瓶頸,可以通過增設緩存、讀寫分離、優化索引和SQL等方式減小資料庫的壓力。如果這些方法並不奏效,那麼可以考慮分庫分表。

  1. 垂直分表:大表拆成若干個小表(每個表欄位不同)
  2. 垂直分庫:一個庫中的表,分到若干個庫中
  3. 水平分表:也叫橫向分表,把一個庫中的表,分為到若干表中(每個表欄位相同)。使用hash和mod,分到不同表中。
  4. 水平分庫分表:把一個庫中的表分到不同庫的相同表中(每個表欄位相同)

分庫分錶帶來的問題是:跨庫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閱:

關於資料庫,可以想像成一個現實中的實物倉庫,其功能是實物的快速存取。隨著貨物和存取的增加,通常會遇到兩個問題:

  1. 貨物太多,倉庫存放不下
  2. 貨物太多,訪問頻繁,導致IO很慢。

所謂的索引、SQL、讀寫分離,不能完全解決上述問題。

一個優化方案是拆掉這個倉庫,重建一個大倉庫,這種方案極其錯誤:

  1. 單機容量是有限的
  2. 不易擴展,無法滿足數據的激增
  3. 大量數據存在一個庫中,導致IO更慢

我們可以新建N個倉庫,把不同業務的貨物分配到不同的倉庫中。這就是資料庫的垂直拆分,優點是貨物的存放更有條理,能減輕IO壓力。缺點是要配置多個數據源,而且跨庫的事務和級聯都變得非常複雜。

垂直拆分以後,倉庫A存在業務A的貨物,但是由於業務A的貨物非常大,是的倉庫A還是覺得業務很大,所以得把貨物分到其他倉庫中,這就是資料庫的水平拆分。這麼做的好處是顯而易見的,但也帶了一些問題:

  1. 服務層不知道業務A的數據存放在哪一個庫中,所以需要SQL路由。
  2. 不同庫的相同表中,主鍵的生成不能依賴Oracle的sequence或者MySQL的自增欄位。
  3. 查詢數據要查詢多個庫,而且數據量很大時,需要分頁查詢,這會非常複雜。

說了這麼多,似乎可以從資料庫窺見一些計算機存儲的奧秘:

不管是什麼層次的存儲器,容量都是有限的,而數據可以無限增長,所以保持存儲高效的不二法門就是不讓存儲器存放過多的數據。雖然看起來是句廢話,但卻是頂層設計的圭臬。

參考資料:

分庫分表的幾種常見形式以及可能遇到的難

大眾點評訂單系統分庫分表實踐 -

《大型網路系統與Java中間件實踐》


推薦閱讀:

什麼鬼!基於備份恢復的數據還能變多?
【案例分享】SequoiaDB+Spark搭建醫院臨床知識庫系統
循序漸進學習如何在 MariaDB 中配置主從複製

TAG:資料庫 |