MySQL 常用分庫分表方案,都在這裏了!

轉自:尜尜人物

www.cnblogs.com/littlecharacter/p/9342129.htm

一、數據庫瓶頸

不管是 IO 瓶頸,還是 CPU 瓶頸,最終都會導致數據庫的活躍連接數增加,進而逼近甚至達到數據庫可承載活躍連接數的閾值。在業務 Service 來看就是,可用數據庫連接少甚至無連接可用。接下來就可以想象了吧(併發量、吞吐量、崩潰)。

1、IO 瓶頸

第一種:磁盤讀 IO 瓶頸,熱點數據太多,數據庫緩存放不下,每次查詢時會產生大量的 IO,降低查詢速度 -> 分庫和垂直分表

第二種:網絡 IO 瓶頸,請求的數據太多,網絡帶寬不夠 -> 分庫

2、CPU 瓶頸

第一種:SQL 問題,如 SQL 中包含 join,group by,order by,非索引字段條件查詢等,增加 CPU 運算的操作 -> SQL 優化,建立合適的索引,在業務 Service 層進行業務計算。

第二種:單表數據量太大,查詢時掃描的行太多,SQL 效率低,CPU 率先出現瓶頸 -> 水平分表

二、分庫分表

1、水平分庫

  1. 概念:以字段爲依據,按照一定策略(hash、range 等),將一個中的數據拆分到多個中。

  2. 結果:

  1. 場景:系統絕對併發量上來了,分表難以根本上解決問題,並且還沒有明顯的業務歸屬來垂直分庫。

  2. 分析:庫多了,io 和 cpu 的壓力自然可以成倍緩解。

2、水平分表

  1. 概念:以字段爲依據,按照一定策略(hash、range 等),將一個中的數據拆分到多個中。

  2. 結果:

  1. 場景:系統絕對併發量並沒有上來,只是單表的數據量太多,影響了 SQL 效率,加重了 CPU 負擔,以至於成爲瓶頸。

  2. 分析:表的數據量少了,單次 SQL 執行效率高,自然減輕了 CPU 的負擔。

3、垂直分庫

  1. 概念:以爲依據,按照業務歸屬不同,將不同的拆分到不同的中。

  2. 結果:

  1. 場景:系統絕對併發量上來了,並且可以抽象出單獨的業務模塊。

  2. 分析:到這一步,基本上就可以服務化了。例如,隨着業務的發展一些公用的配置表、字典表等越來越多,這時可以將這些表拆到單獨的庫中,甚至可以服務化。再有,隨着業務的發展孵化出了一套業務模式,這時可以將相關的表拆到單獨的庫中,甚至可以服務化。

4、垂直分表

  1. 概念:以字段爲依據,按照字段的活躍性,將中字段拆到不同的(主表和擴展表)中。

  2. 結果:

  1. 場景:系統絕對併發量並沒有上來,表的記錄並不多,但是字段多,並且熱點數據和非熱點數據在一起,單行數據所需的存儲空間較大。以至於數據庫緩存的數據行減少,查詢時會去讀磁盤數據產生大量的隨機讀 IO,產生 IO 瓶頸。

  2. 分析:可以用列表頁和詳情頁來幫助理解。垂直分表的拆分原則是將熱點數據(可能會冗餘經常一起查詢的數據)放在一起作爲主表,非熱點數據放在一起作爲擴展表。這樣更多的熱點數據就能被緩存下來,進而減少了隨機讀 IO。拆了之後,要想獲得全部數據就需要關聯兩個表來取數據。但記住,千萬別用 join,因爲 join 不僅會增加 CPU 負擔並且會講兩個表耦合在一起(必須在一個數據庫實例上)。關聯數據,應該在業務 Service 層做文章,分別獲取主表和擴展表數據然後用關聯字段關聯得到全部數據。

三、分庫分表工具

  1. sharding-sphere:jar,前身是 sharding-jdbc;

  2. TDDL:jar,Taobao Distribute Data Layer;

  3. Mycat:中間件。

注:工具的利弊,請自行調研,官網和社區優先。

四、分庫分表步驟

根據容量(當前容量和增長量)評估分庫或分表個數 -> 選 key(均勻)-> 分表規則(hash 或 range 等)-> 執行(一般雙寫)-> 擴容問題(儘量減少數據的移動)。

五、分庫分表問題

1、非 partition key 的查詢問題

基於水平分庫分表,拆分策略爲常用的 hash 法。

  1. 端上除了 partition key 只有一個非 partition key 作爲條件查詢
  1. 端上除了 partition key 不止一個非 partition key 作爲條件查詢
  1. 後臺除了 partition key 還有各種非 partition key 組合條件查詢

2、非 partition key 跨庫跨表分頁查詢問題

基於水平分庫分表,拆分策略爲常用的 hash 法。

注:用 **NoSQL 法 ** 解決(ES 等)。

3、擴容問題

基於水平分庫分表,拆分策略爲常用的 hash 法。

  1. 水平擴容庫(升級從庫法)

    注:擴容是成倍的。

  2. 水平擴容表(雙寫遷移法)

    第一步:(同步雙寫)修改應用配置和代碼,加上雙寫,部署;第二步:(同步雙寫)將老庫中的老數據複製到新庫中;第三步:(同步雙寫)以老庫爲準校對新庫中的老數據;第四步:(同步雙寫)修改應用配置和代碼,去掉雙寫,部署;

注:雙寫是通用方案。

六、分庫分表總結

  1. 分庫分表,首先得知道瓶頸在哪裏,然後才能合理地拆分(分庫還是分表?水平還是垂直?分幾個?)。且不可爲了分庫分表而拆分。

  2. 選 key 很重要,既要考慮到拆分均勻,也要考慮到非 partition key 的查詢。

  3. 只要能滿足需求,拆分規則越簡單越好。

七、分庫分表示例

示例 GitHub 地址:https://github.com/littlecharacter4s/study-sharding

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/67ksP7TrJt9wX9PDaNh06A