mycat是一個(gè)中間件代理層贸伐,對(duì)研發(fā)無感知
1新蟆、一個(gè)徹底開源的耕姊,面向企業(yè)應(yīng)用開發(fā)的大數(shù)據(jù)庫集群 ??????
2、支持事務(wù)栅葡、ACID茉兰、可以替代MySQL的加強(qiáng)版數(shù)據(jù)庫 ??????
3、一個(gè)可以視為MySQL集群的企業(yè)級(jí)數(shù)據(jù)庫欣簇,用來替代昂貴的Oracle集群
4规脸、一個(gè)融合內(nèi)存緩存技術(shù)、NoSQL技術(shù)熊咽、HDFS大數(shù)據(jù)的新型SQL Server ??
5莫鸭、結(jié)合傳統(tǒng)數(shù)據(jù)庫和新型分布式數(shù)據(jù)倉庫的新一代企業(yè)級(jí)數(shù)據(jù)庫產(chǎn)品 ????
6、一個(gè)新穎的數(shù)據(jù)庫中間件產(chǎn)品
優(yōu)點(diǎn):
1横殴、開發(fā)無感知
2被因、增刪節(jié)點(diǎn)程序不需要重啟
3、跨語言(java 衫仑、php)
缺點(diǎn):
1梨与、性能下降多了一層
2、不支持跨數(shù)據(jù)庫
MyCat經(jīng)典實(shí)用場(chǎng)景
1文狱、單純的讀寫分離粥鞋,此時(shí)配置最為簡(jiǎn)單,支持讀寫分離瞄崇,主從切換
2呻粹、分表分庫,對(duì)于超過1000 萬的表進(jìn)行分片,最大支持1000 億的單表分片
3、多租戶應(yīng)用拧抖,每個(gè)應(yīng)用一個(gè)庫,但應(yīng)用程序只連接Mycat绸罗,從而不改造程序本身,實(shí)現(xiàn)多租戶化
4、報(bào)表系統(tǒng),借助于Mycat的分表能力庄萎,處理大規(guī)模報(bào)表的統(tǒng)計(jì)
5踪少、替代Hbase塘安,分析大數(shù)據(jù)作為海量數(shù)據(jù)實(shí)時(shí)查詢的一種簡(jiǎn)單有效方案,比如100 億條頻繁查詢的記錄需要在3 秒內(nèi)查詢出來結(jié)果援奢,
6兼犯、除了基于主鍵的查詢,還可能存在范圍查詢或其他屬性查詢,此時(shí)Mycat 可能是最簡(jiǎn)單有效的選擇
mycat的使用對(duì)研發(fā)是無感知的切黔,但是運(yùn)維成本較大砸脊,涉及到一些概念
邏輯庫(sehema),
邏輯表(table)纬霞,
配置分片(dataNode)凌埂,
配置物理庫分片映射(dataHost)
==========================================================================================================================================================================
Sharding-JDBC
1、垂直分庫
垂直分庫相對(duì)來說是比較好理解的诗芜,核心理念就四個(gè)字:專庫專用瞳抓。
按業(yè)務(wù)類型對(duì)表進(jìn)行分類,像訂單伏恐、支付孩哑、優(yōu)惠券、積分等相應(yīng)的表放在對(duì)應(yīng)的數(shù)據(jù)庫中翠桦。開發(fā)者不可以跨庫直連別的業(yè)務(wù)數(shù)據(jù)庫横蜒,想要其他業(yè)務(wù)數(shù)據(jù),對(duì)應(yīng)業(yè)務(wù)方可以提供API接口销凑,這就是微服務(wù)的初始形態(tài)丛晌。
垂直分庫很大程度上取決于業(yè)務(wù)的劃分,但有時(shí)候業(yè)務(wù)間的劃分并不是那么清晰斗幼,比如:訂單數(shù)據(jù)的拆分要考慮到與其他業(yè)務(wù)間的關(guān)聯(lián)關(guān)系茵乱,并不是說直接把訂單相關(guān)的表放在一個(gè)庫里這么簡(jiǎn)單。
在一定程度上孟岛,垂直分庫似乎提升了一些數(shù)據(jù)庫性能瓶竭,可實(shí)際上并沒有解決由于單表數(shù)據(jù)量過大導(dǎo)致的性能問題,所以就需要配合水平切分方式來解決渠羞。
垂直分表是基于數(shù)據(jù)表的列(字段)為依據(jù)切分的斤贰,是一種大表拆小表的模式。
例如:一張order訂單表次询,將訂單金額荧恍、訂單編號(hào)等訪問頻繁的字段,單獨(dú)拆成一張表屯吊,把?blob?類型這樣的大字段或訪問不頻繁的字段送巡,拆分出來創(chuàng)建一個(gè)單獨(dú)的擴(kuò)展表?work_extend?,這樣每張表只存儲(chǔ)原表的一部分字段盒卸,再將拆分出來的表分散到不同的庫中骗爆。
我們知道數(shù)據(jù)庫是以行為單位將數(shù)據(jù)加載到內(nèi)存中,這樣拆分以后核心表大多是訪問頻率較高的字段蔽介,而且字段長(zhǎng)度也都較短摘投,因而可以加載更多數(shù)據(jù)到內(nèi)存中煮寡,來增加查詢的命中率,減少磁盤IO犀呼,以此來提升數(shù)據(jù)庫性能幸撕。
垂直切分的優(yōu)點(diǎn):
① 業(yè)務(wù)間數(shù)據(jù)解耦,不同業(yè)務(wù)的數(shù)據(jù)進(jìn)行獨(dú)立的維護(hù)外臂、監(jiān)控坐儿、擴(kuò)展。
② 在高并發(fā)場(chǎng)景下宋光,一定程度上緩解了數(shù)據(jù)庫的壓力挑童。
垂直切分的缺點(diǎn):
① 提升了開發(fā)的復(fù)雜度,由于業(yè)務(wù)的隔離性跃须,很多表無法直接訪問站叼,必須通過接口方式聚合數(shù)據(jù)。
② 分布式事務(wù)管理難度增加菇民。
③ 數(shù)據(jù)庫還是存在單表數(shù)據(jù)量過大的問題尽楔,并未根本上解決,需要配合水平切分第练。
2.?水平切分
前邊說了垂直切分還是會(huì)存在單庫阔馋、表數(shù)據(jù)量過大的問題,當(dāng)我們的應(yīng)用已經(jīng)無法在細(xì)粒度的垂直切分時(shí)娇掏,依舊存在單庫讀寫呕寝、存儲(chǔ)性能瓶頸,這時(shí)就要配合水平切分一起了婴梧,水平切分能大幅提升數(shù)據(jù)庫性能下梢。
2、水平分庫
水平分庫是把同一個(gè)表按一定規(guī)則拆分到不同的數(shù)據(jù)庫中塞蹭,每個(gè)庫可以位于不同的服務(wù)器上孽江,以此實(shí)現(xiàn)水平擴(kuò)展,是一種常見的提升數(shù)據(jù)庫性能的方式番电。
這種方案往往能解決單庫存儲(chǔ)量及性能瓶頸問題岗屏,但由于同一個(gè)表被分配在不同的數(shù)據(jù)庫中,數(shù)據(jù)的訪問需要額外的路由工作漱办,因此系統(tǒng)的復(fù)雜度也被提升了这刷。
例如訂單DB_1、訂單DB_1娩井、訂單DB_3?三個(gè)數(shù)據(jù)庫內(nèi)有完全相同的表?order暇屋,我們?cè)谠L問某一筆訂單時(shí)可以通過對(duì)訂單的訂單編號(hào)取模的方式?訂單編號(hào) mod 3 (數(shù)據(jù)庫實(shí)例數(shù))?,指定該訂單應(yīng)該在哪個(gè)數(shù)據(jù)庫中操作撞牢。
(2)?水平分表
水平分表是在同一個(gè)數(shù)據(jù)庫內(nèi)率碾,把一張大數(shù)據(jù)量的表按一定規(guī)則叔营,切分成多個(gè)結(jié)構(gòu)完全相同表屋彪,而每個(gè)表只存原表的一部分?jǐn)?shù)據(jù)所宰。
例如:一張order訂單表有 900萬數(shù)據(jù),經(jīng)過水平拆分出來三個(gè)表畜挥,order_1仔粥、order_2、order_3蟹但,每張表存有數(shù)據(jù) 300萬躯泰,以此類推。
水平分表盡管拆分了表华糖,但子表都還是在同一個(gè)數(shù)據(jù)庫實(shí)例中麦向,只是解決了單一表數(shù)據(jù)量過大的問題,并沒有將拆分后的表分散到不同的機(jī)器上客叉,還在競(jìng)爭(zhēng)同一個(gè)物理機(jī)的CPU诵竭、內(nèi)存、網(wǎng)絡(luò)IO等兼搏。要想進(jìn)一步提升性能卵慰,就需要將拆分后的表分散到不同的數(shù)據(jù)庫中,達(dá)到分布式的效果佛呻。
水平切分的優(yōu)點(diǎn):
① 解決高并發(fā)時(shí)單庫數(shù)據(jù)量過大的問題裳朋,提升系統(tǒng)穩(wěn)定性和負(fù)載能力。
② 業(yè)務(wù)系統(tǒng)改造的工作量不是很大吓著。
水平切分的缺點(diǎn):
① 跨分片的事務(wù)一致性難以保證鲤嫡。
② 跨庫的join關(guān)聯(lián)查詢性能較差。
③ 擴(kuò)容的難度和維護(hù)量較大绑莺,(拆分成幾千張子表想想都恐怖)泛范。
3.一定規(guī)則是什么
我們上邊提到過很多次一定規(guī)則?,這個(gè)規(guī)則其實(shí)是一種路由算法紊撕,就是決定一條數(shù)據(jù)具體應(yīng)該存在哪個(gè)數(shù)據(jù)庫的哪張表里罢荡。
常見的有取模算法?和?范圍限定算法
(1)?取模算法
按字段取模(對(duì)hash結(jié)果取余數(shù) (hash() mod N),N為數(shù)據(jù)庫實(shí)例數(shù)或子表數(shù)量)是最為常見的一種切分方式对扶。
還拿order訂單表舉例区赵,先對(duì)數(shù)據(jù)庫從 0 到 N-1進(jìn)行編號(hào),對(duì)?order?訂單表中?work_no?訂單編號(hào)字段進(jìn)行取模浪南,得到余數(shù)?i笼才,i=0存第一個(gè)庫,i=1存第二個(gè)庫络凿,i=2存第三個(gè)庫....以此類推骡送。
這樣同一筆訂單的數(shù)據(jù)都會(huì)存在同一個(gè)庫昂羡、表里,查詢時(shí)用相同的規(guī)則摔踱,用work_no訂單編號(hào)作為查詢條件虐先,就能快速的定位到數(shù)據(jù)。
優(yōu)點(diǎn):
數(shù)據(jù)分片相對(duì)比較均勻派敷,不易出現(xiàn)請(qǐng)求都打到一個(gè)庫上的情況蛹批。
缺點(diǎn):
這種算法存在一些問題,當(dāng)某一臺(tái)機(jī)器宕機(jī)篮愉,本應(yīng)該落在該數(shù)據(jù)庫的請(qǐng)求就無法得到正確的處理腐芍,這時(shí)宕掉的實(shí)例會(huì)被踢出集群,此時(shí)算法變成hash(userId) mod N-1试躏,用戶信息可能就不再在同一個(gè)庫中了猪勇。
(2)?范圍限定算法
按照時(shí)間區(qū)間?或?ID區(qū)間?來切分,比如:我們切分的是用戶表颠蕴,可以定義每個(gè)庫的?User?表里只存10000條數(shù)據(jù)泣刹,第一個(gè)庫只存?userId?從1 ~ 9999的數(shù)據(jù),第二個(gè)庫存?userId?為10000 ~ 20000裁替,第三個(gè)庫存?userId?為 20001~ 30000......以此類推项玛,按時(shí)間范圍也是同理。
優(yōu)點(diǎn):
? ? ? 單表數(shù)據(jù)量是可控的
? ? ? 水平擴(kuò)展簡(jiǎn)單只需增加節(jié)點(diǎn)即可弱判,無需對(duì)其他分片的數(shù)據(jù)進(jìn)行遷移
? ? ? 能快速定位要查詢的數(shù)據(jù)在哪個(gè)庫
缺點(diǎn):
由于連續(xù)分片可能存在數(shù)據(jù)熱點(diǎn)襟沮,比如按時(shí)間字段分片,可能某一段時(shí)間內(nèi)訂單驟增昌腰,可能會(huì)被頻繁的讀寫开伏,而有些分片存儲(chǔ)的歷史數(shù)據(jù),則很少被查詢遭商。
(3)?分庫分表的難點(diǎn)
1) 分布式事務(wù)
由于表分布在不同庫中固灵,不可避免會(huì)帶來跨庫事務(wù)問題。一般可使用"三階段提交?"和 "兩階段提交" 處理劫流,但是這種方式性能較差巫玻,代碼開發(fā)量也比較大。通常做法是做到最終一致性的方案祠汇,如果不苛求系統(tǒng)的實(shí)時(shí)一致性仍秤,只要在允許的時(shí)間段內(nèi)達(dá)到最終一致性即可,采用事務(wù)補(bǔ)償?shù)姆绞健?/p>
這里我應(yīng)用阿里的分布式事務(wù)框架Seata來做分布式事務(wù)的管理可很,后邊會(huì)結(jié)合實(shí)際案例诗力。
2) 分頁、排序我抠、跨庫聯(lián)合查詢
分頁苇本、排序袜茧、聯(lián)合查詢是開發(fā)中使用頻率非常高的功能,但在分庫分表后瓣窄,這些看似普通的操作卻是讓人非常頭疼的問題笛厦。將分散在不同庫中表的數(shù)據(jù)查詢出來,再將所有結(jié)果進(jìn)行匯總整理后提供給用戶康栈。
3) 分布式主鍵
分庫分表后數(shù)據(jù)庫的自增主鍵意義就不大了递递,因?yàn)槲覀儾荒芤揽繂蝹€(gè)數(shù)據(jù)庫實(shí)例上的自增主鍵來實(shí)現(xiàn)不同數(shù)據(jù)庫之間的全局唯一主鍵喷橙,此時(shí)一個(gè)能夠生成全局唯一ID的系統(tǒng)是非常必要的啥么,那么這個(gè)全局唯一ID就叫?分布式ID。
4) 讀寫分離
不難發(fā)現(xiàn)大部分主流的關(guān)系型數(shù)據(jù)庫都提供了主從架構(gòu)的高可用方案贰逾,而我們需要實(shí)現(xiàn)讀寫分離?+?分庫分表悬荣,讀庫與寫庫都要做分庫分表處理,后邊會(huì)有具體實(shí)戰(zhàn)案例疙剑。
5) 數(shù)據(jù)脫敏
數(shù)據(jù)脫敏氯迂,是指對(duì)某些敏感信息通過脫敏規(guī)則進(jìn)行數(shù)據(jù)轉(zhuǎn)換,從而實(shí)現(xiàn)敏感隱私數(shù)據(jù)的可靠保護(hù)言缤,如身份證號(hào)嚼蚀、手機(jī)號(hào)、卡號(hào)管挟、賬號(hào)密碼等個(gè)人信息轿曙,一般這些都需要進(jìn)行做脫敏處理。
4.?分庫分表工具
我還是那句話僻孝,盡量不要自己造輪子导帝,因?yàn)樽约涸斓妮喿涌赡懿荒敲磮A,業(yè)界已經(jīng)有了很多比較成熟的分庫分表中間件穿铆,我們根據(jù)自身的業(yè)務(wù)需求挑選您单,將更多的精力放在業(yè)務(wù)實(shí)現(xiàn)上。
sharding-jdbc(當(dāng)當(dāng))
TSharding(蘑菇街)
Atlas(奇虎360)
Cobar(阿里巴巴)
MyCAT(基于Cobar)
Oceanus(58同城)
Vitess(谷歌)
為什么選sharding-jdbc
sharding-jdbc是一款輕量級(jí)?Java?框架荞雏,以?jar?包形式提供服務(wù)虐秦,是屬于客戶端產(chǎn)品不需要額外部署,它相當(dāng)于是個(gè)增強(qiáng)版的?JDBC?驅(qū)動(dòng)凤优;相比之下像?Mycat?這類需要單獨(dú)的部署服務(wù)的服務(wù)端產(chǎn)品悦陋,就稍顯復(fù)雜了。況且我想把更多精力放在實(shí)現(xiàn)業(yè)務(wù)别洪,不想做額外的運(yùn)維工作叨恨。
sharding-jdbc的兼容性也非常強(qiáng)大,適用于任何基于?JDBC?的?ORM?框架挖垛,如:JPA痒钝,?Hibernate秉颗,Mybatis,Spring JDBC Template?或直接使用的?JDBC送矩。
完美兼容任何第三方的數(shù)據(jù)庫連接池蚕甥,如:DBCP,?C3P0栋荸,?BoneCP菇怀,Druid,?HikariCP?等晌块,幾乎對(duì)所有關(guān)系型數(shù)據(jù)庫都支持爱沟。
不難發(fā)現(xiàn)確實(shí)是比較強(qiáng)大的一款工具,而且它對(duì)項(xiàng)目的侵入性很小匆背,幾乎不用做任何代碼層的修改呼伸,也無需修改SQL語句,只需配置待分庫分表的數(shù)據(jù)表即可钝尸。