Mycat中介軟體的下發準則

2021-09-05 13:08:07 字數 4698 閱讀 1843

**:

mycat中的路由結果是通過分片欄位和分片方法來確定的。例如下圖中的乙個mycat分庫方案:

如果查詢條件中有 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的處理邏輯如下圖:

在有排序呢條件的情況下,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時有分頁排序,請考慮放棄!

join操作的sql如下

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

此時能查詢出結果

這個sql在各個單獨的分片db中都查不出結果,也就是說mycat不能查詢出正確的結果集。

設計使用mycat時如果要進行表join操作,要確保兩個表的關聯字段具有相同的資料分布,否則請考慮放棄!

mycat並沒有根據二階段提交協議實現 xa事務,而是只保證 prepare 階段資料一致性的 弱xa事務 ,實現過程如下:

應用開啟事務後mycat標識該連線為非自動提交,比如前端執行

mysql>begin;

mycat不會立即把命令傳送到db節點上,等後續下發sql時,mycat從連線池獲取非自動提交的連線去執行。

mycat會等待各個節點的返回結果,如果都執行成功,mycat給該連線標識為 prepare ready 狀態,如果有乙個節點執行失敗,則標識為 rollback 狀態。

執行完成後mycat等待前端傳送 commit 或 rollback 命令。傳送 commit 命令時,mycat檢測當前連線是否為 prepare ready 狀態,若是,則將 commit 命令傳送到各個db節點。

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

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

總結:1)非分片字段查詢時,mycat會下發到後端所有資料庫伺服器查詢

2)當分頁查詢時,會產生偏移量問題。正確的姿勢是,改寫sql語句,然後下發。

3)盡量避免mycat聯合查詢時,兩張表的對應記錄不在同乙個資料庫中(多庫多表查詢)

4)分布式事務。begin時不下發,下一條語句到來時,下發。等待所有節點返回結果。

MySQL 中介軟體 mycat 的使用

先在伺服器上建立三個資料庫 然後將配置 上面建立的三個庫為 mycat 的資料來源 conf schema.xml 設定 user 表 資料節點分別為上面設定的 dn1,dn2,dn3,分片規則為id根據 auto sharding long 的規則劃分到某個資料節點 在 conf rule.xml...

mycat中介軟體配置詳情介紹

目標 低成本的將現有的單機資料庫和應用平滑遷移到 雲 端,解決資料儲存和業務規模迅速增長情況下的資料瓶頸問題。關鍵特性 支援 sql 92標準 支援mysql集群,可以作為proxy使用 支援jdbc連線oracle db2 sql server,將其模擬為mysql server使用 支援gale...

MyCat 資料庫集群中介軟體

中文網 權威指南 document mycat definitive guide.pdf 主要功能 分庫分表 橫切,縱切 主從複製讀寫分離,弱xa事務,資料庫集群監控 1 安裝配置 在win環境下測試,在 mycat conf下存放著配置檔案,雙擊 mycat bin startup nowrap....