[zebra源碼]如果定位到多個分庫或分表怎么執(zhí)行的?

假設(shè)分庫分表情況如下

  • 分庫 id0:分表 test_0 、 test_1
  • 分庫 id1: 分表 test_2、 test_3

sql語句: select test.* from test

一、路由結(jié)果

DefaultRouter#router 路由出來的結(jié)果兩個 RouterResult, 每個里邊有多個分表的sql, 即所有分庫下的所有test分表

dbName: id0
sqls:
- SELECT test_0.* \nFROM test_0
- SELECT test_1.* \nFROM test_1

dbName: id1
sqls:
- SELECT test_2.* \nFROM test_2
- SELECT test_3.* \nFROM test_3

二、執(zhí)行過程

如果路由定位到多個分庫,會根據(jù)并發(fā)度n,將每個分庫的sql語句 拆分成n個任務(wù),放入線程池執(zhí)行
默認單庫并發(fā)度 concurrentLevel = 1, 執(zhí)行過程為

(1) 執(zhí)行分庫id0里各分表的sql

  • 從分庫id0 對應(yīng)的數(shù)據(jù)源中一個數(shù)據(jù)連接,創(chuàng)建 (SELECT test_0.* \nFROM test_0)的 statement
  • 從分庫id0 對應(yīng)的數(shù)據(jù)源中一個數(shù)據(jù)連接,創(chuàng)建l (SELECT test_1.* \nFROM test_1 )的statement
  • 把這兩個statement包裹到一個線程task中

(2) 執(zhí)行分庫id1里各分表的sql

  • 從分庫id1 對應(yīng)的數(shù)據(jù)源中一個數(shù)據(jù)連接,創(chuàng)建 (SELECT test_2.* \nFROM test_2 ) 的statement
  • 從分庫id1 對應(yīng)的數(shù)據(jù)源中一個數(shù)據(jù)連接,創(chuàng)建l (SELECT test_3.* \nFROM test_3 )的statement
  • 把這兩個statement包裹到一個線程task中

(3) 把這兩個task 丟到 SQLThreadPoolExecutor 中執(zhí)行, 阻塞等待執(zhí)行完畢

三、結(jié)果集合并

ShardResultSet#init() -> ShardResultSetMerger.merge 合并這四個 ResultSet

ShardResultSet 內(nèi)部包含多個sql執(zhí)行的結(jié)果集 ResultSet, 它實現(xiàn)了 ResultSet ,當從它遍歷查詢結(jié)果的時候,會根據(jù) MergeContext( join、limit…etc)來組合結(jié)果數(shù)據(jù)

debug單測入口:

com.dianping.zebra.shard.jdbc.MultiDBPreparedStatementLifeCycleTest#testSingleRouterResult1

總結(jié)

路由定位到多個分庫或分表的執(zhí)行邏輯:

ShardPrepardStatement#normalSelectExecute 會依次執(zhí)行這多個路由目標分庫 RouterResult 內(nèi)的語句,然后 ShardPrepardStatement#executeQueryByOriginal執(zhí)行單個分庫內(nèi)的所有sql, 如果它發(fā)現(xiàn)有多個sql需要執(zhí)行,則會根據(jù) 單庫并發(fā)度的配置 concurrentLevel=1

(1) 默認concurrentLevel = 1 ,每個分庫內(nèi)不同表的sql, 先創(chuàng)建對應(yīng)的 statement, 然后會打包到一個task里

(2) 如果 concurrentLevel > 1, 則每個分庫會獲取 concurrentLevel 個數(shù)據(jù)庫連接,將這幾條分表的sql均攤到這幾個數(shù)據(jù)庫連接,創(chuàng)建多個statement, 包成 concurrentLevel 個線程task

(3) 然后丟到j(luò)ava線程池中并發(fā)執(zhí)行 ,然后阻塞等待執(zhí)行完畢,獲取結(jié)果

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容