您當前的位置:首頁 > 歷史

史上最詳盡的 MySQL 分庫分表文章

作者:由 終端研發部 發表于 歷史時間:2021-06-26

大家好,我是你們的小於哥。文章集中整理總結mysql分庫分表開源產品,分散式資料庫的設計,以及實際應用案例等相關內容,部分附上本文作者實際應用過程中的理解。

1、先丟擲兩個問題

2、 基本概念

3、 分片

3。1 水平拆分,垂直拆分都是什麼?

3。2 為什麼分表?

2。3 為什麼分庫?

3。4 分散式事務?

3。5 小結

3。6 如何自己實現分庫分表?

4、 分組

4。1 為什麼分組?

4。2 同步,非同步,半同步

4。3 ha方案

5、 應用案例

5。1 記錄一次mongo遷移mysql的過程(分庫分表使用jproxy)

5。2 記錄一次異構具有複雜分片規則資料庫的過程

文章集中整理總結mysql分庫分表開源產品,分散式資料庫的設計,以及實際應用案例等相關內容,部分附上本文作者實際應用過程中的理解。

本文感謝 sjdbc,mycat,姜承堯,林濤 等文章提供的精彩介紹。

1、先丟擲兩個問題

問題一、當mysql單表資料量爆炸時,你怎麼辦?

問題二、當你的資料庫無法承受高強度io時你怎麼辦?

2、 基本概念

2.1 談資料庫分片需要首先確定以下概念

單庫,就是一個庫

史上最詳盡的 MySQL 分庫分表文章

分片(sharding),分片解決

擴充套件性

問題,屬於水平拆分,引入分片,就引入了

資料路由

分割槽鍵

的概念。分表解決的是資料量過大的問題,分庫解決的是資料庫效能瓶頸的問題。

史上最詳盡的 MySQL 分庫分表文章

分組(group),分組解決

可用性

問題,分組通常透過主從複製(

replication

)的方式實現。(各種可用級別方案單獨介紹)

史上最詳盡的 MySQL 分庫分表文章

網際網路公司資料庫實際軟體架構是(

大資料量下

):又分片,又分組(如下圖)

史上最詳盡的 MySQL 分庫分表文章

3、 分片

3.1 水平拆分,垂直拆分都是什麼?

史上最詳盡的 MySQL 分庫分表文章

分割槽表?1)若不走分割槽鍵很容易出現全表鎖,併發上來後簡直是災難。2)自己分庫分表,自己掌控業務場景、訪問模式,可控。mysql分割槽表官方介紹是針對myisam做的最佳化,你知道他怎麼玩的?分半天還是一個ibdata是不是很尷尬

3.2 為什麼分表?

關係型資料庫在大於一定資料量的情況下檢索效能會急劇下降。在面對網際網路海量資料情況時,所有資料都存於一張表,顯然會輕易超過資料庫表可承受的

資料量閥值

。這個單表可承受的資料量閥值,需根據資料庫和併發量的差異,透過實際測試獲得。

水平拆分如果能預估規模,越早做成本越低。

3.3 為什麼分庫?

單純的分表雖然可以解決資料量過大導致檢索變慢的問題,但無法解決過多併發請求訪問同一個庫,導致資料庫響應變慢的問題。所以通常

水平拆分都至少要採用分庫

的方式,用於一併解決大資料量和

高併發

的問題。這也是部分開源的分片資料庫中介軟體只支援分庫的原因。

3.4 分散式事務?

但分表也有不可替代的適用場景。最常見的分表需求是事務問題。同在一個庫則不需考慮分散式事務,善於使用同庫不同表可有效避免分散式事務帶來的麻煩。目前強一致性的分散式事務由於效能問題,導致使用起來並不一定比不分庫分錶快。目前採用最終一致性的柔性事務居多。分表的另一個存在的理由是,過多的資料庫例項不利於運維管理。

mysql本身?訊息補償?2PC?

3.5 小結

綜上所述,最佳實踐是合理地配合使用分庫+分表。

3.6 如何自己實現分庫分表?

dao層,首先

透過分割槽鍵算出庫名錶名

(如shardKey%shardNum 算出來表index如y,然後y/(shardNum/sourceNum)=x,y是表下標,x是庫下標)。

把source從spring容器中拿出來

,把表名當引數傳進去,拼成分片後的sql。

思路大概是(select … from order where … -> 先拿到db_x的source 然後 select … from order_y where …)

你想這麼幹?你已經成功了。當然淘寶和噹噹的架構師也是這麼幹的。

3.7 SO,不需要我們親自動手,其實你需要做的只是按照實際需求挑選而已。

史上最詳盡的 MySQL 分庫分表文章

3.8 重點介紹兩個產品,先不說具體配置,只說思想

sharding-jdbc(所處位置,通用資料訪問層,部署在客戶端的jar包,用於將使用者的SQL路由到指定的資料庫中)

盜一波圖

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

jproxy

jproxy是什麼?

jproxy提供MariaDB, MySQL等資料庫的統一接入訪問,擁有流量過載保護,資料自動拆分,可配置路由規則,資料無縫遷移等功能。應用場景:資料需要分庫分表,自動擴容的應用。

史上最詳盡的 MySQL 分庫分表文章

為什麼分片都是2的n次方?a % (2^n) 等價於 a & (2^n - 1) 其中一個原因就是位運算

擴容?虛擬桶。極限就是一片一庫。

演變過程 cobar->mycat->jproxy

mycat是什麼?

簡單的說,就是:一個徹底開源的,面向企業應用開發的“大資料庫叢集”。支援事務、ACID、可以替代Mysql的加強版資料庫,一個的資料庫中介軟體產品。

其優勢具有:

基於阿里開源的Cobar產品而研發,Cobar的穩定性、可靠性、優秀的架構和效能

擁有眾多成熟的使用案例

強大的團隊(其參與者都是5年以上資深軟體工程師、架構師、DBA等)

開源,創新,持續更新

盜一波圖

史上最詳盡的 MySQL 分庫分表文章

4、 分組

4.1 為什麼分組?

分組解決

可用性

問題

mysql的ha 網洛上的都是vip漂移實現的

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

方案一:MYSQL主從複製(單活)

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

方案二:雙主(單活),failover比單主簡單

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

方案三:雙主配SAN儲存(單活)

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

方案四:DRBD 雙主配DRBD (單活)

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

方案五:NDB CLUSTER

史上最詳盡的 MySQL 分庫分表文章

共享儲存? 不需要複製了 更高的一致性

真正的高併發場景,什麼架構都抗不住,老老實實用快取。

需要大量讀的場景儘量做到最終一致性。

4.2 同步,非同步,半同步

非同步複製 (mysql預設)

Master將事件寫入binlog,但並不知道Slave是否或何時已經接收且已處理。當Slave準備好才會向Master請求binlog。缺點:不能保證一些事件都能夠被所有的Slave所接收。

同步複製

Master提交事務,直到事務在

所有的Slave

都已提交,此時才會返回客戶端,事務執行完畢。缺點:完成一個事務可能會有很大的延遲。

半同步複製

半同步複製工作的機制處於同步和非同步之間,Master的事務提交阻塞,

只要一個Slave

已收到該事務的事件且已記錄。它不會等待所有的Slave都告知已收到,且它只是接收,並不用等其完全執行且提交。

半同步複製的步驟:

i。當Slave主機連線到Master時,能夠檢視其是否處於半同步複製的機制。

ii。當Master上開啟半同步複製的功能時,至少應該有一個Slave開啟其功能。此時,一個執行緒在Master上提交事務將受到阻塞,直到得知一個已開啟半同步複製功能的Slave已收到此事務的所有事件,或等待超時。

iii。當一個事務的事件都已寫入其relay-log中且已重新整理到磁碟上,Slave才會告知已收到。

iv。如果等待超時,也就是Master沒被告知已收到,此時Master會自動轉換為非同步複製的機制。當至少一個半同步的Slave趕上了,Master與其Slave自動轉換為半同步複製的機制。

v。半同步複製的功能要在Master,Slave都開啟,半同步複製才會起作用;否則,只開啟一邊,它依然為非同步複製。

4.3 ha方案

MHA

MMM

5、 應用案例

5.1 記錄一次mongo遷移mysql的過程(分庫分表使用jproxy)

mongo怎麼了?跟分片無關的部分簡單說。

mongo很好,只是業界並沒有成熟的MongoDB運維經驗,jd too。像高併發的系統 訂單和庫存 商品 還是拿nosql把,高併發的寫,也不會打掛他,比如hbase,頂多GC頻繁點,但是也是可用的。一致性完全可以CAS搞定,而不是mysql的排他鎖。

遷移資料庫的一個方案

中心化(統一入口)

雙寫(先同步寫mysql如果發生異常改非同步,儘量避免服務不可用)

倒庫(jproxy支援透過遊標形式全量遍歷庫-逐個表操作,可以利用其非同步同步資料)

資料校驗

切庫提供服務

史上最詳盡的 MySQL 分庫分表文章

去mongo+最佳化方案(此處引入了分片的概念)

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

壓測與效能

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

史上最詳盡的 MySQL 分庫分表文章

去mongo任務線

型別

任務

備註

影線系統

風險

5.2 記錄一次異構具有複雜分片規則資料庫的過程

5.2.1 難點

交易庫存複雜的分片規則,資料量大,更新頻繁,一致性保證。

回到本源,快取+佇列

史上最詳盡的 MySQL 分庫分表文章

5.2.2 不跑題,我們就說分片部分,如何接手一個複雜分片規則的資料庫?

有多複雜?​ 6000+表,28個庫,4套分片規則。(解決方案 sharding-jdbc)

作者:隔壁老王的隔壁老劉

連結:httpss://

http://

tinyurl。com/yznrkltz

補充:MySQL使用為什麼要分庫分表

可以用說用到MySQL的地方,只要資料量一大, 馬上就會遇到一個問題,要分庫分表。

這裡引用一個問題為什麼要分庫分表呢?MySQL處理不了大的表嗎?

1、其實是可以處理的大表的。我所經歷的專案中單表物理上檔案大小在80G多,單表記錄數在5億以上,而且這個表 屬於一個非常核用的表:朋友關係表。

但這種方式可以說不是一個最佳方式。因為面臨檔案系統如Ext3檔案系統對大於大檔案處理上也有許多問題。

2、這個層面可以用xfs檔案系統進行替換。但MySQL單表太大後有一個問題是不好解決: 表結構調整相關的操作基本不在可能。所以大項在使用中都會面監著分庫分表的應用。

3、從Innodb本身來講資料檔案的Btree上只有兩個鎖, 葉子節點鎖和子節點鎖,可以想而知道,當發生頁拆分或是新增新葉時都會造成表裡不能寫入資料。

所以分庫分表還就是一個比較好的選擇了。

標簽: 分表  分庫  分片  資料庫  slave