更新時間:2021-06-15 16:21:04 來源:動力節點 瀏覽1462次
數據量大到單機hold不住,而又不希望調整架構切換為NoSQL數據庫,這個場景下可以考慮適用mycat。當然,使用前也應該做規劃,哪些表需要分片等等。另外mycat對跨庫join的支持不是很好,在使用mycat的時候要注意規避這種場景。其實不至這一種方式,還有其他的一些數據庫中間件。比如說TIDB或者是shardingsphere。shardingsphere沒有使用過,但是TIDB的的確確可以用于生產環境。
MyCat中的路由結果是通過分片字段和分片方法來確定的。例如下圖中的MyCat分庫方案
根據tt_waybill表的id字段來進行分片
分片方法為id值取3的模,根據模值確定在DB1,DB2,DB3中的某個分片
如果查詢條件中有 id 字段的情況還好,查詢將會落到某個具體的分片。例如:
mysql>select * from tt_waybill where id = 12330;
此時Mycat會計算路由結果
12330 % 3 = 0 –> DB1
并將該請求路由到DB1上去執行。
如果查詢條件中沒有 分片字段 條件,例如:
mysql>select * from tt_waybill where waybill_no =88661;
此時Mycat無法計算路由,便發送到所有節點上執行:
DB1 –> select * from tt_waybill where waybill_no =88661;
DB2 –> select * from tt_waybill where waybill_no =88661;
DB3 –> select * from tt_waybill where waybill_no =88661;
如果該分片字段選擇度高,也是業務常用的查詢維度,一般只有一個或極少數個DB節點命中(返回結果集)。示例中只有3個DB節點,而實際應用中的DB節點數遠超過這個,假如有50個,那么前端的一個查詢,落到MySQL數據庫上則變成50個查詢,會極大消耗Mycat和MySQL數據庫資源。如果設計使用Mycat時有非分片字段查詢,請考慮放棄!
分頁排序
先看一下Mycat是如何處理分頁操作的,假如有如下Mycat分庫方案:一張表有30份數據分布在3個分片DB上,具體數據分布如下:
DB1:[0,1,2,3,4,10,11,12,13,14]
DB2:[5,6,7,8,9,16,17,18,19]
DB3:[20,21,22,23,24,25,26,27,28,29]
當應用執行如下分頁查詢時
mysql>select * from table limit 2;
Mycat將該SQL請求分發到各個DB節點去執行,并接收各個DB節點的返回結果
DB1: [0,1]
DB2: [5,6]
DB3: [20,21]
但Mycat向應用返回的結果集取決于哪個DB節點最先返回結果給Mycat。如果Mycat最先收到DB1節點的結果集,那么Mycat返回給應用端的結果集為[0,1],如果Mycat最先收到DB2節點的結果集,那么返回給應用端的結果集為[5,6]。也就是說,相同情況下,同一個SQL,在Mycat上執行時會有不同的返回結果。
在Mycat中執行分頁操作時必須顯示加上排序條件才能保證結果的正確性,下面看一下Mycat對排序分頁的處理邏輯。
假如在前面的分頁查詢中加上了排序條件(假如表數據的列名為id)。比如如下所示:
mysql>select * from table order by id limit 2;
在有排序的條件的情況下,Mycat接收到各個DB節點的返回結果后,對其進行最小堆運算,計算出所有結果集中最小的兩條記錄 [0,1] 返回給應用。但是,當排序分頁中有 偏移量 (offset)時,處理邏輯又有不同。假如應用的查詢SQL如下:
mysql>select * from table order by id limit 5,2;
Mycat將各個DB節點返回的數據[10,11],[16,17],[20,21]經過最小堆計算后返回給應用的結果集是[10,11]。可是,對于應用而言,該表的所有數據明明是0-29這30個數據的集合,limit 5,2操作返回的結果集應該是[5,6],如果返回[10,11]則是錯誤的處理邏輯。所以Mycat在處理有偏移量的排序分頁時是另外一套邏輯——改寫SQL。如下圖:
MyCat在下發有 limit m,n 的SQL語句時會對其進行改寫,改寫成 limit 0, m+n 來保證查詢結果的邏輯正確性。所以,Mycat發送到后端DB上的SQL語句是:
mysql>select * from table order by id limit 0,7;
各個DB返回給Mycat的結果集是
DB1: [0,1,2,3,4,10,11]
DB2: [5,6,7,8,9,16,17]
DB3: [20,21,22,23,24,25,26]
經過最小堆計算后得到最小序列 [0,1,2,3,4,5,6] ,然后返回偏移量為5的兩個結果為 [5,6] 。
雖然Mycat返回了正確的結果,但是仔細推敲發現這類操作的處理邏輯是及其消耗(浪費)資源的。應用需要的結果集為2條,Mycat中需要處理的結果數為21條。也就是說,對于有t個DB節點的全分片limit m,n操作,Mycat需要處理的數據量為(m+n)*t個。比如實際應用中有50個DB節點,要執行limit 1000,10操作,則Mycat處理的數據量為50500條,返回結果集為10,當偏移量更大時,內存和CPU資源的消耗則是數十倍增加。如果設計使用MyCat時有分頁排序,請考慮放棄!
以上就是動力節點Java培訓機構的小編針對“Mycat分表的原理是什么”的內容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業老師隨時為你服務。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習