MySQL數(shù)據(jù)庫(kù)分庫(kù)分表的方案
一、什么是分庫(kù)分表?
分庫(kù):從單個(gè)數(shù)據(jù)庫(kù)拆分成多個(gè)數(shù)據(jù)庫(kù)的過(guò)程,將數(shù)據(jù)散落在多個(gè)數(shù)據(jù)庫(kù)中。
分表:從單張表拆分成多張表的過(guò)程,將數(shù)據(jù)散落在多張表內(nèi)。
二、為什么分庫(kù)分表?
隨著平臺(tái)的業(yè)務(wù)發(fā)展,數(shù)據(jù)可能會(huì)越來(lái)越多,甚至達(dá)到億級(jí)。以MySQL為例,單庫(kù)數(shù)據(jù)量在5000萬(wàn)以內(nèi)性能比較好,超過(guò)閾值后性能會(huì)隨著數(shù)據(jù)量的增大而明顯降低。單表的數(shù)據(jù)量超過(guò)1000w,性能也會(huì)下降嚴(yán)重。這就會(huì)導(dǎo)致查詢一次所花的時(shí)間變長(zhǎng),并發(fā)操作達(dá)到一定量時(shí)可能會(huì)卡死,甚至把系統(tǒng)給拖垮。
三、怎么選擇分庫(kù)分表策略?
切分方案 | 解決的問(wèn)題 |
---|---|
只分庫(kù)不分表 | 數(shù)據(jù)庫(kù)讀?寫(xiě)QPS過(guò)高,數(shù)據(jù)庫(kù)連接數(shù)不足 |
只分表不分庫(kù) | 單表數(shù)據(jù)過(guò)大,存儲(chǔ)性能遇到瓶頸 |
即分庫(kù)又分表 | 連接數(shù)不足+數(shù)據(jù)量過(guò)大引起的存儲(chǔ)性能瓶頸 |
四、分庫(kù)分表方式及帶來(lái)的問(wèn)題?
分庫(kù)分表有效的緩解了大數(shù)據(jù)、高并發(fā)帶來(lái)的性能和壓力,也能突破網(wǎng)絡(luò)IO、硬件資源、連接數(shù)的瓶頸,但同時(shí)也帶來(lái)了一些問(wèn)題。
4.1、事務(wù)一致性問(wèn)題
由于分庫(kù)分表把數(shù)據(jù)分布在不同庫(kù)甚至不同服務(wù)器,不可避免會(huì)帶來(lái)分布式事務(wù)問(wèn)題,我們需要額外編程解決該問(wèn)題。
4.2、跨節(jié)點(diǎn)join
在沒(méi)有進(jìn)行分庫(kù)分表前,我們檢索商品時(shí)可以通過(guò)以下SQL對(duì)店鋪信息進(jìn)行關(guān)聯(lián)查詢:
SELECT p.*,s.[店鋪名稱],s.[信譽(yù)] FROM [商品信息] p LEFT JOIN [店鋪信息] s ON p.id = s.[所屬店鋪] WHERE...ORDER BY...LIMIT...
但經(jīng)過(guò)分庫(kù)分表后,[商品信息]和[店鋪信息]不在一個(gè)數(shù)據(jù)庫(kù)或一個(gè)表中,甚至不在一臺(tái)服務(wù)器上,無(wú)法通過(guò)sql語(yǔ)句進(jìn)行關(guān)聯(lián)查詢,我們需要額外編程解決該問(wèn)題。
4.3、跨節(jié)點(diǎn)分頁(yè)、排序和聚合函數(shù)
跨節(jié)點(diǎn)多庫(kù)進(jìn)行查詢時(shí),limit分頁(yè)、order by排序以及聚合函數(shù)等問(wèn)題,就變得比較復(fù)雜了。需要先在不同的分片節(jié)點(diǎn)中將數(shù)據(jù)進(jìn)行排序并返回,然后將不同分片返回的結(jié)果集進(jìn)行匯總和再次排序。例如,進(jìn)行水平分庫(kù)后的商品庫(kù),按ID倒序排序分頁(yè),取第一頁(yè):
以上流程是取第一頁(yè)的數(shù)據(jù),性能影響不大,但由于商品信息的分布在各數(shù)據(jù)庫(kù)的數(shù)據(jù)可能是隨機(jī)的,如果是取第N頁(yè),需要將所有節(jié)點(diǎn)前N頁(yè)數(shù)據(jù)都取出來(lái)合并,再進(jìn)行整體的排序,操作效率可想而知,所以請(qǐng)求頁(yè)數(shù)越大,系統(tǒng)的性能也會(huì)越差。
在使用Max、Min、Sum、Count之類的函數(shù)進(jìn)行計(jì)算的時(shí)候,與排序分頁(yè)同理,也需要先在每個(gè)分片上執(zhí)行相應(yīng)的函數(shù),然后將各個(gè)分片的結(jié)果集進(jìn)行匯總和再次計(jì)算,最終將結(jié)果返回。
4.4、主鍵避重
在分庫(kù)分表環(huán)境中,由于表中數(shù)據(jù)同時(shí)存在不同數(shù)據(jù)庫(kù)中,主鍵值平時(shí)使用的自增長(zhǎng)將無(wú)用武之地,某個(gè)分區(qū)數(shù)據(jù)庫(kù)生成的ID無(wú)法保證全局唯一。因此需要單獨(dú)設(shè)計(jì)全局主鍵,以避免跨庫(kù)主鍵重復(fù)問(wèn)題。
由于分庫(kù)分表之后,數(shù)據(jù)被分散在不同的服務(wù)器、數(shù)據(jù)庫(kù)和表中。因此,對(duì)數(shù)據(jù)的操作也就無(wú)法通過(guò)常規(guī)方式完成,并且它還帶來(lái)了一系列的問(wèn)題。我們?cè)陂_(kāi)發(fā)過(guò)程中需要通過(guò)一些中間件解決這些問(wèn)題,市面上有很多中間件可供我們選擇,其中Sharding-JDBC和mycat較為流行。
五、使用分庫(kù)分表組件幫我們解決一些問(wèn)題
分庫(kù)分表的技術(shù)方案總體上來(lái)講分為兩大類:應(yīng)用層依賴類中間件、中間層代理類中間件。
我們選擇技術(shù)方案時(shí)主要考慮的是,開(kāi)源、開(kāi)發(fā)成本、學(xué)習(xí)成本、技術(shù)復(fù)雜度,技術(shù)使用人數(shù),參考資料的多少等方面。
由于我本人也不是每樣技術(shù)都有用過(guò)。所以在這里只是在能力范圍內(nèi)做一個(gè)初步了解,并進(jìn)行選型。目前這些組件對(duì)于分庫(kù)分表的一些主要問(wèn)題都有相對(duì)完善的解決方案,區(qū)別的只是一些細(xì)節(jié)的問(wèn)題。又結(jié)合目前項(xiàng)目所在只需要輕量級(jí)的分庫(kù)分表。所以我還是比較偏向成本較低,復(fù)雜度較低的方案。
目前市面上使用較多的是,mycat及sharding-jdbc。mycat屬于中間層代理類中間件、sharding-jdbc屬于應(yīng)用層依賴類中間件
5.1. Atlas
奇虎360
關(guān)鍵詞:分庫(kù)分表 Atlas
百度為您找到相關(guān)結(jié)果約707,000個(gè)
中間層代理類中間件
https://github.com/Qihoo360/Atlas github上最后維護(hù)時(shí)間為4年前
優(yōu)點(diǎn)
實(shí)現(xiàn)了讀寫(xiě)分離(并通過(guò)hint/master/可強(qiáng)制?主庫(kù),并且加?了權(quán)重配置可進(jìn)?讀的負(fù)載均衡
??維護(hù)了?套連接池,減少了創(chuàng)建連接帶來(lái)的性能消耗
?持DB動(dòng)態(tài)上下線,?便橫向擴(kuò)展
?持ip過(guò)濾,實(shí)現(xiàn)了簡(jiǎn)單的權(quán)限控制
可記錄所有sql,實(shí)現(xiàn)了簡(jiǎn)單的審計(jì)功能
缺點(diǎn)
使?atlas?直連DB,性能損耗?概是30%-35%左右
使?atlas?直連DB,響應(yīng)時(shí)間?概是直連DB的1.5~2倍
對(duì)分表的?持不是太好,不支持不同庫(kù)間分表
atlas配置暫時(shí)不?持配置參數(shù)的動(dòng)態(tài)加載,如果修改了配置需要重啟atlas,這可能會(huì)對(duì)業(yè)務(wù)有?點(diǎn)的影響(不過(guò)?般可以做ha或者業(yè)務(wù)低峰進(jìn)?重啟,這個(gè)問(wèn)題不是特別迫切)總的來(lái)說(shuō)作為?款開(kāi)源mysql proxy,atlas總體表現(xiàn)還是不錯(cuò)的,持續(xù)壓測(cè)3天都?較穩(wěn)定,只是對(duì)分表的?持不是太好(?如不?持基于時(shí)間的分表模式),?般沒(méi)有太?并發(fā)和對(duì)響應(yīng)時(shí)間嚴(yán)格要求的業(yè)務(wù)可以考慮嘗試使?
5.2. Cobar
阿里
關(guān)鍵詞:分庫(kù)分表 Cobar
百度為您找到相關(guān)結(jié)果約936,000個(gè)
中間層代理類中間件
https://github.com/alibaba/cobar/ github上最后維護(hù)時(shí)間為3年前
5.3. TDDL
阿里 關(guān)鍵詞:分庫(kù)分表 TDDL 百度為您找到相關(guān)結(jié)果約1,080,000個(gè) 應(yīng)用層依賴類中間件
https://github.com/alibaba/tb_tddl
github上TDDL處于停滯狀態(tài),應(yīng)該是部分功能不開(kāi)源了吧。
TDDL 必須要依賴 diamond 配置中心( diamond 是淘寶內(nèi)部使用的一個(gè)管理持久配置的系統(tǒng),目前淘寶內(nèi)部絕大多數(shù)系統(tǒng)的配置)
5.4. heisenberg
百度
關(guān)鍵詞:分庫(kù)分表 heisenberg
百度為您找到相關(guān)結(jié)果約74,900個(gè)
中間層代理類中間件
資料少之又少,不考慮。
5.5. Oceanus
58同城
關(guān)鍵詞:分庫(kù)分表 Oceanus
百度為您找到相關(guān)結(jié)果約118,000個(gè)
https://github.com/wuba/Oceanus github上最后維護(hù)時(shí)間為3年前
資料較少,不考慮。
5.6. OneProxy
原支付寶首席架構(gòu)師樓方鑫開(kāi)發(fā)
關(guān)鍵詞:分庫(kù)分表 OneProxy
百度為您找到相關(guān)結(jié)果約139,000個(gè)
應(yīng)該是不開(kāi)源的
5.7. vitess
YouTube
關(guān)鍵詞:分庫(kù)分表 vitess
百度為您找到相關(guān)結(jié)果約177,000個(gè)
中間層代理類中間件
https://github.com/vitessio/vitess github當(dāng)前活躍
Vitess是一個(gè)用于部署、擴(kuò)展和管理大型MySQL實(shí)例集群的數(shù)據(jù)庫(kù)解決方案。是開(kāi)源的,在github上有很多星星,但是國(guó)內(nèi)的應(yīng)用較少,資料不多。技術(shù)架構(gòu)復(fù)雜,這位更是重量級(jí)。
5.8. TSharding
蘑菇街
關(guān)鍵詞:分庫(kù)分表 TSharding
百度為您找到相關(guān)結(jié)果約100,000個(gè)
https://github.com/baihui212/tsharding github上最后維護(hù)時(shí)間為5年前
應(yīng)該也是不開(kāi)源了
資料少之又少,不考慮
5.9. dal
攜程
關(guān)鍵詞:分庫(kù)分表 dal
百度為您找到相關(guān)結(jié)果約315,000個(gè)
應(yīng)用層依賴類中間件
https://github.com/ctripcorp/dal github當(dāng)前活躍,提供部分教程及demo(需要科學(xué)上網(wǎng))
開(kāi)源范圍包括代碼生成器,Java客戶端和C#客戶端。
國(guó)內(nèi)資料少,需要科學(xué)上網(wǎng)。
5.10. zdal
支付寶
關(guān)鍵詞:分庫(kù)分表 zdal
百度為您找到相關(guān)結(jié)果約30,600個(gè)
中間層代理類中間件
國(guó)內(nèi)資料少,應(yīng)該不開(kāi)源。
5.11.MyCat
基于cobar社區(qū)開(kāi)源
關(guān)鍵詞:分庫(kù)分表 MyCat
百度為您找到相關(guān)結(jié)果約9,030,000個(gè)
中間層代理類中間件
http://mycatone.top/社區(qū)當(dāng)前活躍,無(wú)需科學(xué)上網(wǎng)
資料很多也開(kāi)源,可以考慮。
5.11.1不支持項(xiàng)
DDL語(yǔ)句
- 不支持修改拆分鍵
- 支持物理庫(kù)的視圖視為普通表來(lái)使用
- 僅普通表支持外鍵
- DML語(yǔ)句
DELETE語(yǔ)句
- 不支持涉及分布式運(yùn)算的子查詢。
- 不支持多表delete。
UPDATE語(yǔ)句
- 不支持涉及分布式運(yùn)算的子查詢。
- 不支持多表update。
SELECT語(yǔ)句
- 對(duì)于for update語(yǔ)句會(huì)把sql中出現(xiàn)的表都加鎖。
- 具體是行鎖還是表鎖要看sql語(yǔ)句。
- 不支持SELECT INTO OUTFILE。
SET語(yǔ)句
- 支持SET SESSION級(jí)別的變量,但是不能被預(yù)處理語(yǔ)句引用變量,只有autocommit變量具有正確語(yǔ)義
- 不支持SET GLOBAL級(jí)別的變量
- 不支持SET USER級(jí)別的變量
SHOW語(yǔ)句
- 所有SHOW語(yǔ)句都視為兼容性SQL進(jìn)行處理,發(fā)往prototype節(jié)點(diǎn)處理,所以不具備分布式語(yǔ)義高級(jí)功能
- 不支持用戶自定義數(shù)據(jù)類型(改代碼), 自定義函數(shù)(改代碼)
- 支持物理視圖,但是不支持Mycat中的邏輯視圖
- 有限支持存儲(chǔ)過(guò)程
- 不支持游標(biāo)
- 不支持觸發(fā)器
5.12.Sharding-jdbc
當(dāng)當(dāng)開(kāi)源,已加入apache豪華套餐
關(guān)鍵詞:分庫(kù)分表 Sharding-jdbc
百度為您找到相關(guān)結(jié)果約4,240,000個(gè)
應(yīng)用層依賴類中間件
https://shardingsphere.apache.org/ 社區(qū)當(dāng)前活躍,無(wú)需科學(xué)上網(wǎng)
5.12.1不支持項(xiàng)
DataSource 接口
- 不支持 timeout 相關(guān)操作。
Connection 接口
- 不支持存儲(chǔ)過(guò)程,函數(shù),游標(biāo)的操作;
- 不支持執(zhí)行 native SQL;
- 不支持 savepoint 相關(guān)操作;
- 不支持 Schema/Catalog 的操作;
- 不支持自定義類型映射。
Statement 和 PreparedStatement 接口
- 不支持返回多結(jié)果集的語(yǔ)句(即存儲(chǔ)過(guò)程,非 SELECT 多條數(shù)據(jù));
- 不支持國(guó)際化字符的操作。
ResultSet 接口
- 不支持對(duì)于結(jié)果集指針位置判斷;
- 不支持通過(guò)非 next 方法改變結(jié)果指針位置;
- 不支持修改結(jié)果集內(nèi)容;
- 不支持獲取國(guó)際化字符;
- 不支持獲取 Array。
JDBC 4.1
- 不支持 JDBC 4.1 接口新功能。
六、詳細(xì)比較
主要指標(biāo) | Sharding-jdbc | Mycat |
---|---|---|
ORM支持 | 適用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC | 任意 |
事務(wù) | 自帶XA、兩(三)階段事務(wù)、柔性事務(wù)BASE(最終一致) | XA事務(wù) |
分庫(kù) | 支持 | 支持 |
分表 | 支持 | 支持 |
開(kāi)發(fā) | 集成springboot較好,代碼入侵中(需要寫(xiě)些配置類等) | 開(kāi)發(fā)成本小,代碼入侵小 |
所屬公司 | 當(dāng)當(dāng)網(wǎng)開(kāi)源,加入apache | 基于阿里Cobar二次開(kāi)發(fā),社區(qū)維護(hù) |
數(shù)據(jù)庫(kù)支持 | 支持任意實(shí)現(xiàn) JDBC 規(guī)范的數(shù)據(jù)庫(kù),目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 訪問(wèn)的數(shù)據(jù)庫(kù) | Mysql、Oracle、 SQL Server、DB2、mongodb |
活躍度 | 活躍度高 | 社區(qū)活躍度很高,一些公司已在使用 |
監(jiān)控 | 有 | 有 |
讀寫(xiě)分離 | 支持 | 支持 |
資料 | 資料少、github、官網(wǎng)、網(wǎng)上討論貼 | 資料多,github、官網(wǎng)、Q群、書(shū)籍 |
運(yùn)維 | 維護(hù)成本低 | 維護(hù)成本高 |
限制 | 部分JDBC方法不支持、SQL語(yǔ)句限制 | SQL語(yǔ)句限制 |
連接池 | 支持任何第三方的數(shù)據(jù)庫(kù)連接池,如:DBCP, C3P0, BoneCP, HikariCP 等 | 無(wú)要求 |
配置難度 | 一般 | 復(fù)雜 |
總結(jié)
挑選了兩個(gè)使用最多的進(jìn)行了比較,綜合來(lái)看的話感覺(jué)還是Sharding-jdbc更省事一些,無(wú)需部署中間件,只通過(guò)引入jar包進(jìn)行分庫(kù)分表操作,省去一些事情。而且多一個(gè)中間件的話系統(tǒng)穩(wěn)定性也會(huì)降低了。對(duì)與目前來(lái)說(shuō),只需要輕量級(jí)的分庫(kù)分表,功能不需要太多,所以還是選擇Sharding-jdbc合適些。
以上就是MySQL數(shù)據(jù)庫(kù)分庫(kù)分表的方案的詳細(xì)內(nèi)容,更多關(guān)于MySQL數(shù)據(jù)庫(kù)分庫(kù)分表的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mysql大小寫(xiě)敏感導(dǎo)致程序無(wú)法啟動(dòng)的問(wèn)題
這篇文章主要介紹了mysql大小寫(xiě)敏感導(dǎo)致程序無(wú)法啟動(dòng)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11MySQL悲觀鎖與樂(lè)觀鎖的實(shí)現(xiàn)方案
我們知道Mysql并發(fā)事務(wù)會(huì)引起更新丟失問(wèn)題,解決辦法是鎖,所以本文將對(duì)鎖(樂(lè)觀鎖、悲觀鎖)進(jìn)行分析,這篇文章主要給大家介紹了關(guān)于MySQL悲觀鎖與樂(lè)觀鎖方案的相關(guān)資料,需要的朋友可以參考下2021-11-11mysql中union和union?all的使用及注意事項(xiàng)
這篇文章主要給大家介紹了關(guān)于mysql中union和union?all的使用及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2022-08-08MySQL事務(wù)的四大特性以及并發(fā)事務(wù)問(wèn)題解讀
這篇文章主要介紹了MySQL事務(wù)的四大特性以及并發(fā)事務(wù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09MySQL select count(*)計(jì)數(shù)很慢優(yōu)化方案
這篇文章主要介紹了MySQL select count(*)計(jì)數(shù)很慢優(yōu)化方案,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08mysql實(shí)現(xiàn)merge into問(wèn)題
文章介紹了在數(shù)據(jù)庫(kù)操作中,如何使用`REPLACE INTO`和`INSERT INTO ON DUPLICATE KEY UPDATE`語(yǔ)句進(jìn)行數(shù)據(jù)更新和插入操作,如果不想創(chuàng)建唯一性索引,可以通過(guò)存儲(chǔ)過(guò)程實(shí)現(xiàn),文章通過(guò)實(shí)驗(yàn)和驗(yàn)證,展示了這兩種方法的實(shí)際效果2024-12-12MySql中的IFNULL、NULLIF和ISNULL用法詳解
本文主要介紹了MySql中的IFNULL、NULLIF和ISNULL用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03mysql中將null值轉(zhuǎn)換為0的語(yǔ)句
mysql中將null值轉(zhuǎn)換為0的語(yǔ)句,在mysql數(shù)據(jù)庫(kù)開(kāi)發(fā)中,如果后期添加了字段那么這些值為空值null,我們?cè)谑褂谜咝枰獙ull轉(zhuǎn)換為0方便后期的控制就需要下面的代碼了。2011-02-02解決Mysql5.7.17在windows下安裝啟動(dòng)時(shí)提示不成功問(wèn)題
這篇文章主要介紹了解決Mysql5.7.17在windows下安裝啟動(dòng)時(shí)提示不成功問(wèn)題,需要的朋友可以參考下2017-03-03