mysql 多张表公用一个序列_Mysql--序列3--分库分表策略
分庫分表是存儲層設(shè)計中一個普遍而重大的問題,什么時候分?怎么分?分完之后引發(fā)的新問題,比如不能Join、分布式事務(wù)? 本篇將從最基本的策略出發(fā),逐步深入講解這里面涉及的一序列策略。
分庫-業(yè)務(wù)分拆 & 數(shù)據(jù)隔離
分庫的首先目的就是做“業(yè)務(wù)分拆“,關(guān)于業(yè)務(wù)分拆,在前面的序列文章“分布式系統(tǒng)--基本思想?yún)R總“中已經(jīng)有闡述。通過業(yè)務(wù)分拆,把一個大的復(fù)雜系統(tǒng)拆成多個業(yè)務(wù)子系統(tǒng),之間通過RPC或消息中間件通信。這樣做既便于團(tuán)隊成員的職責(zé)分工,也便于對未來某個系統(tǒng)做擴(kuò)展。
另外一個考慮角度是“數(shù)據(jù)隔離”。如果你把核心業(yè)務(wù)的數(shù)據(jù)和非核心業(yè)務(wù)數(shù)據(jù)放在一個庫里面,不分輕重,同等對待。這樣如果因為非核心業(yè)務(wù)把DB搞掛了,核心業(yè)務(wù)也受到牽連。分開之后,區(qū)別對待,投入的開發(fā)和運維人力也不一樣。
讀多寫少 vs. 讀少寫多
對于業(yè)務(wù)來講,讀多寫少/讀少寫多,所對應(yīng)的策略是不一樣的。
如果是讀多寫少,那你可以通過加從庫、加緩存來解決,不一定要分庫分表。
如果是讀少寫多,或者說寫入的QPS已經(jīng)達(dá)到了DB的瓶頸,這個時候就得考慮分庫分表了。
對于MySQL來講,一般寫入的QPS有3k/s左右,讀寫的QPS可以達(dá)到2萬/s??梢妼懭牒筒樵兊耐掏铝繀^(qū)別是很大的。
分表/分庫
考慮了上面2個策略之后,最后萬不得已,再做分庫分表。因為分庫分表的代價是很大的,意味著代碼要大規(guī)模重構(gòu),以前能用的join,事務(wù)可能都不能用了,需要用新的辦法解決。
垂直切分
垂直切分一般主要用于表的字段太多(比如上百個字段),這種情形通常就對應(yīng)著上層業(yè)務(wù)沒有很好的分拆,解耦。如果做好了上面的“業(yè)務(wù)分拆”,需要這種“垂直切分”的場景可能就會變得很少。下面主要講“水平切分”。
水平切分
當(dāng)表的記錄數(shù)太多,幾千萬,上億,并且有很高的寫入QPS,這個時候就得考慮水平切分了。
一般思路是:保證單表的記錄條數(shù)不要超過千萬,然后根據(jù)總數(shù)據(jù)量估算出要拆多少個表,再考慮把這些表分散到多少個庫里面。
水平切分的最關(guān)鍵問題就是:拆分維度的選擇。
拆分維度(字段)的選擇
比如電商的訂單表,至少有3個查詢維度:訂單id,用戶id,商戶id。那你拆分的時候,根據(jù)哪個維度進(jìn)行拆分呢?
假設(shè)你按用戶id拆分,同一個用戶的所有訂單記錄都落到同1個庫的同1張表里面。那查詢的時候,按user id查,就很容易;
但如果按訂單id,或者商戶id呢?拆分之后,同1個商戶id的訂單,可能被分到了不同的庫、不同的表里面,根本沒辦法查。
對于這種分庫分表之后,其他維度的查詢,一般有以下幾個辦法:
(1)建立一個映射表,建立輔助維度和主維度之間的映射關(guān)系(也就是商戶id和用戶id之間的映射關(guān)系)。? 查詢的時候,根據(jù)商戶id,查出用戶id。再根據(jù)用戶id,來查
(2)業(yè)務(wù)雙寫? 同1份數(shù)據(jù),2套分庫分表。1套按user id切分,1套按商戶id 切分。這個其實也就是我在”分布式系統(tǒng)--基本思想?yún)R總“中所用的“重寫輕讀”
(3)異步雙寫? 還是2套表,只是業(yè)務(wù)單寫。然后通過binlog同步(比如阿里的canal,點評的puma),同步到另外一套表上。
(4)2個維度統(tǒng)一到1個維度? 這個在特殊的場景下可以使用。比如order id和user id就可以統(tǒng)一成1個維度,把user id作為order id中的某幾位,這樣order id中就包含了user id信息。無論按user id,還是order id,都可以hash算出所在的庫,所在的表。
Join問題
分庫分表之后,有些Join就不能用了,針對這種情況,一般有下面幾種解決辦法:? (1)把Join拆成多個單表查詢,上層業(yè)務(wù)代碼進(jìn)行結(jié)果拼裝? (2)提前做寬邊,重寫輕讀? 很多時候,你有這樣的情況:需要把Join的結(jié)果分頁,這個需要利用mysql本身的分頁功能。對于這種不得不用Join的情況,可以另外做一個Join表,提前把結(jié)果Join好。這是“重讀輕寫”,其實也是“空間換時間”的思路。? (3)利用搜索引擎? 對于(2)當(dāng)中提到的場景,還可以利用Lucence,ES這種搜索引擎,把DB中數(shù)據(jù)導(dǎo)入到搜索引擎中來查詢,從而解決Join問題。
分布式事務(wù)
做了分庫之后,純DB的事務(wù)就搞不了了。一般解決辦法都是:通過精心選擇維度,優(yōu)化業(yè)務(wù),避免跨庫的事務(wù),保證所有事務(wù)都落到單庫上面。
如果實在無法避免,那就需要分布式事務(wù)的解決方案了。關(guān)于分布式事務(wù),又是一個系統(tǒng)化的課題,沒有一個標(biāo)準(zhǔn)答案。
后續(xù)文章會詳細(xì)闡述這個問題,敬請期待!
總結(jié)
以上是生活随笔為你收集整理的mysql 多张表公用一个序列_Mysql--序列3--分库分表策略的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 红眼病的症状有哪些
- 下一篇: java string字节数组_java