MySQL分庫分表原理


轉自https://www.jianshu.com/p/7aec260ca1a2

前言

在互聯網還未崛起的時代,我們的傳統應用都有這樣一個特點:訪問量、數據量都比較小,單庫單表都完全可以支撐整個業務。隨着互聯網的發展和用戶規模的迅速擴大,對系統的要求也越來越高。因此傳統的MySQL單庫單表架構的性能問題就暴露出來了。而有下面幾個因素會影響數據庫性能:

  • 數據量
    MySQL單庫數據量在5000萬以內性能比較好,超過閾值后性能會隨着數據量的增大而變弱。MySQL單表的數據量是500w-1000w之間性能比較好,超過1000w性能也會下降。
  • 磁盤
    因為單個服務的磁盤空間是有限制的,如果並發壓力下,所有的請求都訪問同一個節點,肯定會對磁盤IO造成非常大的影響。
  • 數據庫連接
    數據庫連接是非常稀少的資源,如果一個庫里既有用戶、商品、訂單相關的數據,當海量用戶同時操作時,數據庫連接就很可能成為瓶頸。

為了提升性能,所以我們必須要解決上述幾個問題,那就有必要引進分庫分表。

垂直拆分 or 水平拆分?

當我們單個庫太大時,我們先要看一下是因為表太多還是數據量太大,如果是表太多,則應該將部分表進行遷移(可以按業務區分),這就是所謂的垂直切分。如果是數據量太大,則需要將表拆成更多的小表,來減少單表的數據量,這就是所謂的水平拆分。

垂直拆分

  • 垂直分庫
    垂直分庫針對的是一個系統中的不同業務進行拆分,比如用戶一個庫,商品一個庫,訂單一個庫。 一個購物網站對外提供服務時,會同時對用戶、商品、訂單表進行操作。沒拆分之前, 全部都是落到單一的庫上的,這會讓數據庫的單庫處理能力成為瓶頸。如果垂直分庫后還是將用戶、商品、訂單放到同一個服務器上,只是分到了不同的庫,這樣雖然會減少單庫的壓力,但是隨着用戶量增大,這會讓整個數據庫的處理能力成為瓶頸,還有單個服務器的磁盤空間、內存也會受非常大的影響。 所以我們要將其拆分到多個服務器上,這樣上面的問題都解決了,以后也不會面對單機資源問題。

  • 垂直分表
    也就是“大表拆小表”,基於列字段進行的。一般是表中的字段較多,將不常用的, 數據較大,長度較長(比如text類型字段)的拆分到“擴展表“。一般是針對那種幾百列的大表,也避免查詢時,數據量太大造成的“跨頁”問題。

水平拆分

  • 水平分表
    和垂直分表有一點類似,不過垂直分表是基於列的,而水平分表是基於全表的。水平拆分可以大大減少單表數據量,提升查詢效率。
  • 水平分庫分表
    將單張表的數據切分到多個服務器上去,每個服務器具有相應的庫與表,只是表中數據集合不同。 水平分庫分表能夠有效的緩解單機和單庫的性能瓶頸和壓力,突破IO、連接數、硬件資源等的瓶頸。

幾種常用的分庫分表的策略

  • HASH取模
    假設有用戶表user,將其分成3個表user0,user1,user2.路由規則是對3取模,當uid=1時,對應到的是user1,uid=2時,對應的是user2.

  • 范圍分片
    從1-10000一個表,10001-20000一個表。

  • 地理位置分片
    華南區一個表,華北一個表。

  • 時間分片
    按月分片,按季度分片等等,可以做到冷熱數據。

分庫分表后引入的問題

  • 分布式事務問題
    如果我們做了垂直分庫或者水平分庫以后,就必然會涉及到跨庫執行SQL的問題,這樣就引發了互聯網界的老大難問題-"分布式事務"。那要如何解決這個問題呢?
    1.使用分布式事務中間件 2.使用MySQL自帶的針對跨庫的事務一致性方案(XA),不過性能要比單庫的慢10倍左右。3.能否避免掉跨庫操作(比如將用戶和商品放在同一個庫中)

  • 跨庫join的問題
    分庫分表后表之間的關聯操作將受到限制,我們無法join位於不同分庫的表,也無法join分表粒度不同的表, 結果原本一次查詢能夠完成的業務,可能需要多次查詢才能完成。粗略的解決方法: 全局表:基礎數據,所有庫都拷貝一份。 字段冗余:這樣有些字段就不用join去查詢了。 系統層組裝:分別查詢出所有,然后組裝起來,較復雜。

  • 橫向擴容的問題
    當我們使用HASH取模做分表的時候,針對數據量的遞增,可能需要動態的增加表,此時就需要考慮因為reHash導致數據遷移的問題。

  • 結果集合並、排序的問題
    因為我們是將數據分散存儲到不同的庫、表里的,當我們查詢指定數據列表時,數據來源於不同的子庫或者子表,就必然會引發結果集合並、排序的問題。如果每次查詢都需要排序、合並等操作,性能肯定會受非常大的影響。走緩存可能一條路!

使用分庫分表中間件

  • Mycat
    Mycat發展到現在,適用的場景已經很豐富,而且不斷有新用戶給出新的創新性的方案,以下是幾個典型的應用場景:
    單純的讀寫分離,此時配置最為簡單,支持讀寫分離,主從切換
    分表分庫,對於超過1000萬的表進行分片,最大支持1000億的單表分片
    多租戶應用,每個應用一個庫,但應用程序只連接Mycat,從而不改造程序本身,實現多租戶化報表系統,借助於Mycat的分表能力,處理大規模報表的統計
    替代Hbase,分析大數據作為海量數據實時查詢的一種簡單有效方案,比如100億條頻繁查詢的記錄需要在3秒內查詢出來結果,除了基於主鍵的查詢,還可能存在范圍查詢或其他屬性查詢,此時Mycat可能是最簡單有效的選擇.
  • Sharding-JDBC
    當當網開發的簡單易用、輕量級的中間件。

此外還有淘寶的TDDL,支付寶的OneProxy,360的Atlas等。





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM