1.為什么要分庫分表
①分庫分表說白了,就是因為數(shù)據(jù)量太大了,如果你的單表數(shù)據(jù)量都到了千萬級別,那么你的數(shù)據(jù)庫就無法承受高并發(fā)的要求,數(shù)據(jù)庫操作性能就會出現(xiàn)極大的下降。
②數(shù)據(jù)庫并發(fā)量太大了,一般而言,一個數(shù)據(jù)庫最多支撐并發(fā)到2000,這時候一定要進(jìn)行擴容,不然性能會出現(xiàn)嚴(yán)重下降。而且一個健康的單庫并發(fā)值你最好保持在每秒1000左右,不要太大。那么你可以將一個庫的數(shù)據(jù)拆分到多個庫中,訪問的時候就訪問一個庫好了。
2.有哪些分庫分布中間件
比較常見的中間件有cobar、TDDL、atlas、sharding-jdbc、mycat。
①cobar :阿里b2b團隊開發(fā)和開源的,屬于proxy層方案。已經(jīng)好幾年沒有進(jìn)行更新了,基本沒啥人用。而且不支持讀寫分離、存儲過程、跨庫join和分頁等操作。
②TDDL :淘寶團隊開發(fā)的,屬于client層方案,不支持join,但是支持讀寫分離。目前使用的也不多,因為還依賴淘寶的diamond配置管理系統(tǒng)。
③atlas :360開源的,屬于proxy層方案,以前有一些公司在用,但是已經(jīng)好幾年沒有更新了,所以現(xiàn)在用的也不多。
④sharding-jdbc :當(dāng)當(dāng)開源的,屬于client層方案。SQL語法支持多,沒有太多的限制,從2.0版本開始支持分庫分表、讀寫分離、分布式id生成、柔性事務(wù)(最大努力送達(dá)型事務(wù)、TCC事務(wù))。而且現(xiàn)在使用較多。
⑤myCat :基于cobar改造,屬于proxy層方案,支持的功能完善,而且目前應(yīng)該是非?;鸬亩也粩嗔餍械臄?shù)據(jù)庫中間件,社區(qū)很活躍,也有一些公司開始在用了。
3.分布式中間件類型
①proxy類型
proxy類型的中間件就是一個客戶端,需要直接部署一個中間件,去進(jìn)行分庫分表。服務(wù)端將sql發(fā)送到中間件客戶端去進(jìn)行不同表庫的操作。如果中間件客戶端不可用將直接導(dǎo)致無法進(jìn)行分庫分表,而且要走網(wǎng)絡(luò)耗時。
②client
client不需要單獨部署中間件客戶端,運維成本低,中間件就是一個jar包,直接在項目中導(dǎo)入、配置就可以完成分庫分表,而且不需要代理層的二次轉(zhuǎn)發(fā),性能高點,但是遇到升級等操作需要重新發(fā)布版本,各個系統(tǒng)都需要耦合sharding-jbdc的依賴。
4.垂直拆分與水平拆分
①垂直拆分
垂直拆分的意思,就是把一個有很多字段的表給拆分成多個表,或者是多個庫上去。每個庫表的結(jié)構(gòu)都不一樣,每個庫表都包含部分字段。一般來說,會將較少的訪問頻率很高的字段放到一個表里去,然后將較多的訪問頻率很低的字段放到另外一個表里去。因為數(shù)據(jù)庫是有緩存的,你訪問頻率高的行字段越少,就可以在緩存里緩存更多的行,性能就越好。這個一般在表層面做的較多一些。
這個其實挺常見的,不一定我說,大家很多同學(xué)可能自己都做過,把一個大表拆開,訂單表、訂單支付表、訂單商品表。
②水平拆分
水平拆分的意思,就是把一個表的數(shù)據(jù)給弄到多個庫的多個表里去,但是每個庫的表結(jié)構(gòu)都一樣,只不過每個庫表放的數(shù)據(jù)是不同的,所有庫表的數(shù)據(jù)加起來就是全部數(shù)據(jù)。水平拆分的意義,就是將數(shù)據(jù)均勻放更多的庫里,然后用多個庫來抗更高的并發(fā),還有就是用多個庫的存儲容量來進(jìn)行擴容。
③表的拆分
還有表層面的拆分,就是分表,將一個表變成N個表,就是讓每個表的數(shù)據(jù)量控制在一定范圍內(nèi),保證SQL的性能。否則單表數(shù)據(jù)量越大,SQL性能就越差。一般是200萬行左右,不要太多,但是也得看具體你怎么操作,也可能是500萬,或者是100萬。你的SQL越復(fù)雜,就最好讓單表行數(shù)越少。
一般來說,垂直拆分,你可以在表層面來做,對一些字段特別多的表做一下拆分;水平拆分,是并發(fā)承載不了,或者是數(shù)據(jù)量太大,容量承載不了,你給拆了,按什么字段來拆,你自己想好;分表,你考慮一下,你如果哪怕是拆到每個庫里去,并發(fā)和容量都o(jì)k了,但是每個庫的表還是太大了,那么你就分表,將這個表分開,保證每個表的數(shù)據(jù)量并不是很大。
5.兩種分庫分表方式
①range方式
就是每個庫一段連續(xù)的數(shù)據(jù),這個一般是按比如時間范圍來的,但是這種一般較少用,因為很容易產(chǎn)生熱點問題,大量的流量都打在最新的數(shù)據(jù)上了。
range來分,好處在于說,后面擴容的時候,就很容易,因為你只要預(yù)備好,給每個月都準(zhǔn)備一個庫就可以了,到了一個新的月份的時候,自然而然,就會寫新的庫了;缺點,但是大部分的請求,都是訪問最新的數(shù)據(jù)。實際生產(chǎn)用range,要看場景,你的用戶不是僅僅訪問最新的數(shù)據(jù),而是均勻的訪問現(xiàn)在的數(shù)據(jù)以及歷史的數(shù)據(jù)
②hash方式
按照某個字段hash一下均勻分散,這個較為常用。
hash分法,好處在于說,可以平均分配沒給庫的數(shù)據(jù)量和請求壓力;壞處在于說擴容起來比較麻煩,會有一個數(shù)據(jù)遷移的這么一個過程