日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

作者:擁之則安

出處:https://segmentfault.com/a/1190000037545458

1.非分片字段查詢

Mycat中的路由結(jié)果是通過 分片字段 和 分片方法 來確定的。例如下圖中的一個Mycat分庫方案:

  • 根據(jù) tt_waybill 表的 id 字段來進行分片
  • 分片方法為 id 值取 3 的模,根據(jù)模值確定在DB1,DB2,DB3中的某個分片
Mycat數(shù)據(jù)庫中間件

 

如果查詢條件中有 id 字段的情況還好,查詢將會落到某個具體的分片。例如:

MySQL>select * from tt_waybill where id = 12330;

此時Mycat會計算路由結(jié)果

12330 % 3 = 0 –> DB1

并將該請求路由到DB1上去執(zhí)行。

如果查詢條件中沒有 分片字段 條件,例如:

mysql>select * from tt_waybill where waybill_no =88661;

此時Mycat無法計算路由,便發(fā)送到所有節(jié)點上執(zhí)行:

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;

如果該分片字段選擇度高,也是業(yè)務常用的查詢維度,一般只有一個或極少數(shù)個DB節(jié)點命中(返回結(jié)果集)。示例中只有3個DB節(jié)點,而實際應用中的DB節(jié)點數(shù)遠超過這個,假如有50個,那么前端的一個查詢,落到MySQL數(shù)據(jù)庫上則變成50個查詢,會極大消耗Mycat和MySQL數(shù)據(jù)庫資源。

如果設(shè)計使用Mycat時有非分片字段查詢,請考慮放棄!

2.分頁排序

先看一下Mycat是如何處理分頁操作的,假如有如下Mycat分庫方案:

一張表有30份數(shù)據(jù)分布在3個分片DB上,具體數(shù)據(jù)分布如下

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]

(這個示例的場景中沒有查詢條件,所以都是全分片查詢,也就沒有假定該表的分片字段和分片方法)

Mycat數(shù)據(jù)庫中間件

 

當應用執(zhí)行如下分頁查詢時

mysql>select * from table limit 2;

Mycat將該SQL請求分發(fā)到各個DB節(jié)點去執(zhí)行,并接收各個DB節(jié)點的返回結(jié)果

DB1: [0,1]

DB2: [5,6]

DB3: [20,21]

但Mycat向應用返回的結(jié)果集取決于哪個DB節(jié)點最先返回結(jié)果給Mycat。如果Mycat最先收到DB1節(jié)點的結(jié)果集,那么Mycat返回給應用端的結(jié)果集為 [0,1] ,如果Mycat最先收到DB2節(jié)點的結(jié)果集,那么返回給應用端的結(jié)果集為 [5,6] 。也就是說,相同情況下,同一個SQL,在Mycat上執(zhí)行時會有不同的返回結(jié)果。

在Mycat中執(zhí)行分頁操作時必須顯示加上排序條件才能保證結(jié)果的正確性,下面看一下Mycat對排序分頁的處理邏輯。

假如在前面的分頁查詢中加上了排序條件(假如表數(shù)據(jù)的列名為 id )

mysql>select * from table order by id limit 2;

Mycat的處理邏輯如下圖:

Mycat數(shù)據(jù)庫中間件

 

在有排序呢條件的情況下,Mycat接收到各個DB節(jié)點的返回結(jié)果后,對其進行最小堆運算,計算出所有結(jié)果集中最小的兩條記錄 [0,1] 返回給應用。

但是,當排序分頁中有 偏移量 (offset)時,處理邏輯又有不同。假如應用的查詢SQL如下:

mysql>select * from table order by id limit 5,2 ;

如果按照上述排序分頁邏輯來處理,那么處理結(jié)果如下圖:

Mycat數(shù)據(jù)庫中間件

 

Mycat將各個DB節(jié)點返回的數(shù)據(jù) [10,11], [16,17], [20,21] 經(jīng)過最小堆計算后返回給應用的結(jié)果集是 [10,11] 。可是,對于應用而言,該表的所有數(shù)據(jù)明明是 0-29 這30個數(shù)據(jù)的集合, limit 5,2 操作返回的結(jié)果集應該是 [5,6] ,如果返回 [10,11] 則是錯誤的處理邏輯。

所以Mycat在處理 有偏移量的排序分頁 時是另外一套邏輯—— 改寫SQL 。如下圖:

Mycat數(shù)據(jù)庫中間件

 

Mycat在下發(fā)有 limit m,n 的SQL語句時會對其進行改寫,改寫成 limit 0, m+n 來保證查詢結(jié)果的邏輯正確性。所以,Mycat發(fā)送到后端DB上的SQL語句是

mysql>select * from table order by id limit 0,7;

各個DB返回給Mycat的結(jié)果集是

DB1: [0,1,2,3,4,10,11]

DB2: [5,6,7,8,9,16,17]

DB3: [20,21,22,23,24,25,26]

經(jīng)過最小堆計算后得到最小序列 [0,1,2,3,4,5,6] ,然后返回偏移量為5的兩個結(jié)果為 [5,6] 。

雖然Mycat返回了正確的結(jié)果,但是仔細推敲發(fā)現(xiàn)這類操作的處理邏輯是及其消耗(浪費)資源的。應用需要的結(jié)果集為2條,Mycat中需要處理的結(jié)果數(shù)為21條。也就是說,對于有 t 個DB節(jié)點的全分片 limit m, n 操作,Mycat需要處理的數(shù)據(jù)量為 (m+n)*t 個。比如實際應用中有50個DB節(jié)點,要執(zhí)行l(wèi)imit 1000,10操作,則Mycat處理的數(shù)據(jù)量為 50500 條,返回結(jié)果集為 10 ,當偏移量更大時,內(nèi)存和CPU資源的消耗則是數(shù)十倍增加。

如果設(shè)計使用Mycat時有分頁排序,請考慮放棄!

3.任意表JOIN

先看一下在單庫中JOIN中的場景。假設(shè)在某單庫中有 player 和 team 兩張表, player 表中的 team_id 字段與 team 表中的 id 字段相關(guān)聯(lián)。操作場景如下圖:

Mycat數(shù)據(jù)庫中間件

 

JOIN操作的SQL如下

mysql>select p_name,t_name from player p, team t where p.no = 3 and p.team_id = t.id;

此時能查詢出結(jié)果

p_name

t_name

Wade

Heat

如果將這兩個表的數(shù)據(jù)分庫后,相關(guān)聯(lián)的數(shù)據(jù)可能分布在不同的DB節(jié)點上,如下圖:

Mycat數(shù)據(jù)庫中間件

 

這個SQL在各個單獨的分片DB中都查不出結(jié)果,也就是說Mycat不能查詢出正確的結(jié)果集。

設(shè)計使用Mycat時如果要進行表JOIN操作,要確保兩個表的關(guān)聯(lián)字段具有相同的數(shù)據(jù)分布,否則請考慮放棄!

4.分布式事務

Mycat并沒有根據(jù)二階段提交協(xié)議實現(xiàn) XA事務 ,而是只保證 prepare 階段數(shù)據(jù)一致性的 弱XA事務 ,實現(xiàn)過程如下:

應用開啟事務后Mycat標識該連接為非自動提交,比如前端執(zhí)行

mysql>begin;

Mycat不會立即把命令發(fā)送到DB節(jié)點上,等后續(xù)下發(fā)SQL時,Mycat從連接池獲取非自動提交的連接去執(zhí)行。

Mycat數(shù)據(jù)庫中間件

 

Mycat會等待各個節(jié)點的返回結(jié)果,如果都執(zhí)行成功,Mycat給該連接標識為 Prepare Ready 狀態(tài),如果有一個節(jié)點執(zhí)行失敗,則標識為 Rollback 狀態(tài)。

Mycat數(shù)據(jù)庫中間件

 

執(zhí)行完成后Mycat等待前端發(fā)送 commit 或 rollback 命令。發(fā)送 commit 命令時,Mycat檢測當前連接是否為 Prepare Ready 狀態(tài),若是,則將 commit 命令發(fā)送到各個DB節(jié)點。

Mycat數(shù)據(jù)庫中間件

 

但是,這一階段是無法保證一致性的,如果一個DB節(jié)點在 commit 時故障,而其他DB節(jié)點 commit 成功,Mycat會一直等待故障DB節(jié)點返回結(jié)果。Mycat只有收到所有DB節(jié)點的成功執(zhí)行結(jié)果才會向前端返回 執(zhí)行成功 的包,此時Mycat只能一直 waiting 直至_TIMEOUT_,導致事務一致性被破壞。

設(shè)計使用Mycat時如果有分布式事務,得先看是否得保證事務得強一致性,否則請考慮放棄!

作者:擁之則安

出處:https://segmentfault.com/a/1190000037545458

分享到:
標簽:中間件 數(shù)據(jù)庫
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定