當前位置:
首頁 > 知識 > MySQL分庫分表

MySQL分庫分表

什麼是分庫分表

分庫分表指的是將原有的單機單庫的單表橫向拆分到多機、多庫的多表

為什麼要分庫分表

一般情況下,分庫分表主要是為了防止:

  1. 單表數據量太大,行數過多,影響讀寫速度
  2. 單表數據量太大,磁碟佔用過多,難以存儲、備份、還原

什麼時候需要分庫分表

過早優化是萬惡之源。分庫分表成本極高,不到萬不得已,最好不要分庫分表。

分庫分表之前,我們可以先試試以下幾個選項。如果實在必要,再進行分庫分表。

分庫分表前的幾個選項

1. 什麼都不做

很多時候,分庫分表都是世上無事,庸人自擾。

一千萬數據量的表,對我們來說可能是個大表,對MySQL來說,可能毫無壓力。MySQL本身對錶容量沒有做限制,有的用戶甚至用MySQL跑著50億行以上的大表。

一般情況下,MySQL使用InnoDB存儲引擎,InnoDB默認的索引頁大小是16KB。InnoDB的索引使用的數據結構是B+Tree,一個索引節點存儲一個索引值加一個子節點地址。以INT類型的索引為例,一個索引節點佔用4+4=8個位元組,一個索引頁可以存放節點數16KB/8B=2K=2048,構成了一棵2048叉樹。

如果在磁碟上查找索引,1000萬的數據量需要定址log(10**7, 2048)=2.11次,也就是2次IO。100億的數據量需要定址log(10**10, 2048)=3.02次,也就是3次IO。

100億的數據量大約需要磁碟空間10**10*100B=1TB,索引佔用大約10**10*8B=80GB。

所以,只要磁碟、內存和膽子都夠大,用MySQL存儲100億的數據完全沒問題,也完全可以做到毫秒級的讀寫。

2. 優化業務

在對資料庫動手動腳前,先看看業務系統里是不是有不必要的或者可以整合的讀寫,是不是儲存了太多毫無價值的數據

3. 資料庫前端加緩存

適當添加緩存,可以極大地減少資料庫的讀取操作

4. 資料庫加索引

OLTP操作盡量避免全表掃面

5. 資料庫垂直切分

按業務分庫,按冷熱拆表

6. 表分區

將一個表在物理層拆分為多個表,對業務層完全透明。不同的表分區可以指定不同的物理磁碟,加大單表容量,提高並發讀寫速度,方便進行大表的備份與還原。

7. 換存儲引擎

MySQL默認的存儲引擎是InnoDB,在不開啟壓縮的情況下,空間浪費嚴重,一般1000萬行無索引的表佔用空間可達1GB。開啟壓縮後,大概可以節省一半的空間。換用ARCHIVE歸檔引擎,可以大幅提高壓縮率,但是不支持索引,無法進行OLTP查表。換用TokuDB引擎進行折中,可以在支持索引的情況下,大幅壓縮磁碟空間佔用,大約可以節省80%左右的存儲空間。

8. 讀寫分離

搭建MySQL集群,分離讀寫,主機寫,從機讀,主機寫入同步從機。多主機可提高可用性,多從機可提高並發。

走完以上八步,一般情況就不需要分庫分表了。

如何分庫分表

分庫分表主要有以下三種方式:

1. 手工分庫分表

手工建立多庫多表,按照特定的分庫規則,讀取或寫入相應的表。一般用分表鍵對分表數量取余確定分表名。需要大量修改業務層代碼,與業務層耦合嚴重。性能相對較高,但不易維護與擴展。

2. 中間件分庫分表

將手工分庫分表的邏輯抽象為一個中間件,對Java來說是自定義javax.sql.DataSource的實現,將分庫分表邏輯封裝在JDBC後面。對業務層相對透明,但是業界沒有太靠譜的免費解決方案。

3. 代理分庫分表

代理MySQL連接,業務層不連接真實的MySQL伺服器,連接的是MySQL伺服器的代理。MySQL代理伺服器根據配置好的分庫分表規則代理SQL請求,修改並轉發SQL到真實的MySQL伺服器,最後對接收到的請求結果進行歸併處理。對業務層完全透明,但是多開了一個服務,增加了維護成本。

結論

No silver bullet, sometimes no necessay.

MySQL分庫分表

打開今日頭條,查看更多精彩圖片

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

「並發編程」Future模式及JDK中的實現
DataURL, Blob, File, Image之間的關係與轉換

TAG:程序員小新人學習 |