亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Java設計實現多實例多庫查詢

發布時間:2023-03-15 11:40:07 來源:億速云 閱讀:98 作者:iii 欄目:開發技術

這篇文章主要介紹“怎么用Java設計實現多實例多庫查詢”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“怎么用Java設計實現多實例多庫查詢”文章能幫助大家解決問題。

服務的邊界職責 

大數據層取數統一實現入口(數據源的路由,ADB/CK/HBASE... 大數據操作層數據源的路由)

支持多實例、多庫、多表的異構數據查詢

通過 查詢 語義分析+元信息解析,拆解 查詢輸入 中的異構數據源處理,所有異構數據處理采用異步 Callback 方式

解決的問題 

多個數據來源寫入到不同實例、不同庫中,并且一個圈選可以支持圈多個實例(不同庫)中的標簽、事件數據

單表數據量過大,目前只能通過壓縮保留時間解決,需要可以進行按時間段拆表分表查詢數據

單實例配置上限問題,實例升級配置是有上限的成本也很高,支持多實例后就可以使用多實例中等配置無限擴展

無法支持場景 

同一個圈選不支持跨不同類型數據庫混用,類似一個圈選包含了ADB+CK兩種類型數據庫的配置

創建庫表的時候,需要有原則:

不同實例的庫、表名字如果完全一樣,默認他們代表的業務語意也是一致的,如果不一致會出現問題

場景描述: 

怎么用Java設計實現多實例多庫查詢

架構全景圖 

怎么用Java設計實現多實例多庫查詢

傳統數據庫中間件的幾種模式: 

怎么用Java設計實現多實例多庫查詢

種類

優勢

缺點

JAR方式嵌入到應用端

  • 接入簡單,無需單獨部署獨立服務

  • 小數據量場景下速度很快,比原先直連JDBC性能損失很低

  • 調試使用簡單

  • 與應用資源公用,互相影響

  • 大數量場景下會有很多連帶問題

  • 對應用端代碼有一定的入侵性

  • 擴展性差

中間件方式存在,偽裝數據庫代理層

  • 對應用代碼無入侵,只需要修改配置層

  • 資源獨立,不會有捆綁風險

  • 可以分層獨立擴展,可擴展性強

  • 適合大數據量的場景中

  • 讓應用層基本無感知中間件的存在

  • 開發維護成本高

  • 中間件編碼復雜,需要對接開源數據庫的各種代理協議以及字節碼轉換邏輯

  • 小數據量的請求場景中性能比直連的性能損耗嚴重30%~40%

  • 在JDBC上面無法再次擴展,傳輸協議和模型固定

中間件方式存在,不偽裝數據庫代理層

  • 中間件開發簡單,無需對接各種開源數據庫的代理轉換協議

  • 資源獨立,不會有捆綁風險

  • 可以分層獨立擴展,可擴展性強

  • 適合大數據量的場景中

  • 脫離應用端到中間件的JDBC協議,擴展性自由

  • 應用接入層會有感知,配置層缺失了原先的JDBC配置,SQL操作也無法使用原先的數據庫框架而是要將SQL通過Dubbo方式交互

  • 小數據量的請求場景中性能比直連的性能損耗嚴重30%~40%

模塊說明:

模塊名

執行邊界

輸入描述

輸出描述

代理模塊

模型接入

請求模型

結果模型

運行模式模塊

執行線程池處理

在線模式/離線模式

執行線程池

計劃模塊

離線模式和在線模式都需要創建入口執行計劃和執行日志

離線異構取數場景,每一層內嵌取數都是單獨計劃和執行日志,完成后上推執行計劃

計劃存在父子計劃任務

創建計劃

查詢可執行計劃任務數據

更新計劃狀態

可執行的計劃任務

解析模塊

解析查詢請求的參數,轉換成 AST 語法樹

查詢語句,可以是 SQL,可以是 JSON

也可以是規則XML

AST語法樹對象、核心解析模型

權限校驗模塊

判斷token是否有使用的實例、庫、表權限

根據token,庫,表查詢到有權限的實例信息

是否有權限,以及有權限的實例信息

路由模塊

獲取有權限且最優的實例

請求來源的系統,請求來源的庫,請求來源的表

符合權限校驗的實例 ID+庫信息

連接池管理模塊

管理各種數據源的連接池

庫元信息

連接池連接

數據執行模塊

取數執行邏輯,根據改寫后的SQL進行分實例分庫分表查詢,最終匯總到臨時表,在進行完整原始SQL改寫的執行

大數據量臨時表通過生成SQL執行語句導入到OSS

取數語句分析拆分后的執行語句

異構數據的話返回實例名+庫名+表名

非異構數據返回數據結果集

計費模塊

根據臨時表數據量,跨庫+跨表數量進行公式化計費

AST語法樹對象、SQL

最終成本費用

復用模塊

數據復用的邏輯判斷

執行語句,間隔時間

是否復用模型

熔斷模塊

對執行中的計劃進行強制熔斷,沒有任何業務邏輯,只是提供熔斷標示

計劃ID

是否熔斷

項目模塊依賴描述:(開發分之:multiple-instances)(項目名:datacenter-night-watchman) 

怎么用Java設計實現多實例多庫查詢

怎么用Java設計實現多實例多庫查詢

模塊間邏輯交互

  • 支持單實例多庫查詢

  • 支持多實例多庫查詢

  • 支持單實例單庫查詢

  • 異構數據統一異步匯總臨時表,非異構數據默認實時傳輸返回

怎么用Java設計實現多實例多庫查詢

運行模式模塊  

  • 在線模式(只支持非異構取數),先落地實時計劃表,然后實時交互查詢數據,返回數據

  • 離線模式(支持異構和非異構取數),先實時創建父子計劃,然后返回父計劃ID,異步調度執行計劃進行取數,接入方通過計劃ID查詢計劃狀態和異構存儲表

  • 每一個計劃都對應一個取數任務

怎么用Java設計實現多實例多庫查詢

計劃表結構:(Mysql-watchman庫) 

怎么用Java設計實現多實例多庫查詢

CREATE TABLE `extract_data_calculation_log`  (   `id` bigint(32) NOT NULL,   `exe_id` bigint(32) NOT NULL COMMENT '計劃表主鍵ID',   `last_exe_id` bigint(32) NOT NULL COMMENT '最大用戶ID',   `exe_state` tinyint(1) NOT NULL COMMENT '執行狀態,1-執行中 2-執行成功  3-執行失敗',   `create_time` datetime(0) NOT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '記錄創建時間',   `updat_time` datetime(0) NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '記錄更新時間',   `version` int(8) NOT NULL COMMENT '記錄版本號',   `exe_quantity` bigint(32) NULL COMMENT '數據冗余字段,執行的數據量',   PRIMARY KEY (`id`),   INDEX `exe`(`circle_exe_id`) ) COMMENT = '提取數據日志表';  
CREATE TABLE `extract_data_execute`  (   `id` bigint(32) NOT NULL,   `storage_result` json NOT NULL COMMENT '{"type":"存儲類型,1-adb  2-rmq  3-oss  4-ck","result":"adb/ck 代表表名,rmq代表topic,oss代表存儲地址","example":"實例地址","database":"庫地址"}',   `create_time` timestamp(0) NOT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '記錄創建時間',   `updat_time` timestamp(0) NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '記錄更新時間',   `plan_logic` tinyint(1) NOT NULL DEFAULT 1 COMMENT '計劃邏輯,1-正常 2-暫不執行',   `priority` int(8) NOT NULL DEFAULT 1 COMMENT '任務優先級,數字越小優先級越高',   `data_type` tinyint(1) NOT NULL COMMENT '執行模式,1-立即執行  2-離線執行',   `parent_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '父級計劃ID ',   `rewrite_result` json NOT NULL COMMENT '改寫模型',   PRIMARY KEY (`id`) ) COMMENT = '數據取數計劃表';  
ALTER TABLE `extract_data_calculation_log` ADD CONSTRAINT `exe` FOREIGN KEY (`circle_exe_id`) REFERENCES `extract_data_execute` (`id`); 
ALTER TABLE `extract_data_execute` ADD CONSTRAINT `config` FOREIGN KEY (`circle_config_id`) REFERENCES `circle_config` (`id`);

查詢解析模塊 

  • 解析模塊使用shardingjdbc5內部的sql解析引擎,druid很久不更新了,很多新的語法支持不好

  • 解析模塊代碼寫到底層工具包,包含SQL、JSON解析

怎么用Java設計實現多實例多庫查詢

Sharding5 的解析引擎已經支持多種數據庫包含各種數據庫新增的函數語法解析,主要是Mysql、Pg、Sqlserver、Oracle 

<dependency>     
  <groupId>org.apache.shardingsphere</groupId>     
  <artifactId>shardingsphere-sql-parser-engine</artifactId> 
</dependency> 
 
<dependency>     
  <groupId>org.apache.shardingsphere</groupId>     
  <artifactId>shardingsphere-sql-parser-mysql</artifactId> 
</dependency> 
 
<dependency>     
  <groupId>org.apache.shardingsphere</groupId>     
  <artifactId>shardingsphere-infra-federation-optimizer</artifactId> </dependency> 
  
<dependency>     
  <groupId>org.apache.calcite</groupId>     
  <artifactId>calcite-core</artifactId> 
</dependency>

Clickhouse和ADB目前都是支持原生mysql協議的,那么進入的數據庫解析方言使用mysql引擎即可 

ShardingSphere解析引擎模塊代碼示例: 

public static void main(String[] args) {     
    CacheOption cacheOption = new CacheOption( 128, 1024L, 4 );     			  SQLParserEngine sqlParserEngine = new SQLParserEngine( "MySQL", cacheOption, true );     
    ParseContext parseContext = sqlParserEngine.parse( "select * from user where id in (select id from city where id = 11);", true );     
    SQLVisitorEngine visitorEngine = new SQLVisitorEngine( "MySQL", "STATEMENT", new Properties() );     
    SelectStatement selectStatement = visitorEngine.visit( parseContext );      	SelectStatementConverter selectStatementConverter = new SelectStatementConverter();     
    SqlSelect sqlSelect = (SqlSelect) selectStatementConverter.convertToSQLNode( selectStatement );     
    System.out.println( sqlSelect.getSelectList() );     
    System.out.println( sqlSelect.getFrom() );     
    System.out.println( sqlSelect.getWhere() ); 
}  
輸出結果: 查詢字段:* 查詢表:user 查詢條件:`id` IN (SELECT `id` FROM `city` WHERE `id` = 11)

怎么用Java設計實現多實例多庫查詢

解析模塊注意點: 

  • 解析引擎只做原始解析,然后封裝到輸出模型中

  • 解析輸出模型需要考慮嵌套SQL的模型存在以及同層級union的模型存在

  • 解析輸出模型聚合根已經調整好,缺失的字段或者模型在進行微調

怎么用Java設計實現多實例多庫查詢

權限校驗模塊:(此模塊代碼接口預留,邏輯暫不實現) 

  • 有了圈選解析模型,已經獲取到使用的實例、庫、表相關所有信息了

  • 根據入參token判斷實例和庫的權限情況

  • 表結構需要有,數據需要按照規范填入,后期做代碼邏輯實現

  • 暫時無實現,所以默認所有實例都可用,全部返回到模型

怎么用Java設計實現多實例多庫查詢

改寫引擎 

  • 負責將可能涉及到多實例、多庫、多表的聯合查詢拆分

  • 拆分過程中需要考慮聯合查詢的where條件、group by 條件、order by 條件

  • 如果解析模型傳遞過來的數據中,不存在跨庫場景,那么改寫引擎不進行任何操作邏輯

改寫案例描述: 

  • 將復合嵌套的SQL平鋪,按照庫為單位,最內層開始為最小粒度

  • 每一層都會同時存在4中類型改寫語句

  • 取數語句

  • 替換符語句

  • 聚合語句


  • 建表語句

怎么用Java設計實現多實例多庫查詢

改寫模型描述: 

怎么用Java設計實現多實例多庫查詢

路由模塊 

  • 通過權限模型中返回的有權限的實例,判斷最優的CPU實例

  • 根據實例+庫名去連接池模塊中獲取相應的連接池信息

  • 分庫分表邏輯后續實現,暫不做設計

鏈接池模塊 

需要支持通配符方式的連接配置,案例:

# 同一個實例下不同庫的通配連接 db.datasource.watchman.jdbcUrl=jdbc:mysql://A.mysql.rds.aliyuncs.com:3306/{db1,db2,db3} 
db.datasource.watchman.username={A.db1:dw_datacenter_A,A.db2:dw_datacenter_B,A.db3:dw_datacenter_C} db.datasource.watchman.password= {A.db1:password_A,A.db2:password_B,A.db3:password_C}   
# 不同實例下同庫的通配連接 db.datasource.watchman.jdbcUrl=jdbc:mysql://{A,B}.mysql.rds.aliyuncs.com:3306/db1 
db.datasource.watchman.username={A.db1:dw_datacenter_A,B.db1:dw_datacenter_B} db.datasource.watchman.password= {A.db1:password_A,B.db2:password_B}   
# 同一個實例下不同庫的區間通配連接 db.datasource.watchman.jdbcUrl=jdbc:mysql://A.mysql.rds.aliyuncs.com:3306/{db[1~20]} 
db.datasource.watchman.username={A.db1:dw_datacenter_A,A.db2:dw_datacenter_B,A.db3:dw_datacenter_C,A.db...} db.datasource.watchman.password= {A.db1:password_A,A.db2:password_B,A.db3:password_C,A.db...}   
# 多數據源連接配置 db.datasource.watchman.jdbcUrl.ck=jdbc:mysql://A.mysql.rds.aliyuncs.com:3306/{db[1~20]} 
db.datasource.watchman.username.ck={A.db1:dw_datacenter_A,A.db2:dw_datacenter_B,A.db3:dw_datacenter_C,A.db...} db.datasource.watchman.password.ck= {A.db1:password_A,A.db2:password_B,A.db3:password_C,A.db...}  db.datasource.watchman.jdbcUrl.adb=jdbc:mysql://A.mysql.rds.aliyuncs.com:3306/{db[1~20]} 
db.datasource.watchman.username.adb={A.db1:dw_datacenter_A,A.db2:dw_datacenter_B,A.db3:dw_datacenter_C,A.db...} db.datasource.watchman.password.adb= {A.db1:password_A,A.db2:password_B,A.db3:password_C,A.db...}

鏈接池內部使用druid框架,沒有單獨對數據源進行druid參數配置的話全部采用守夜人默認提供的運行參數,如果需要單獨對不同數據源進行配置,那么原先druid的配置加上對應的后綴

db.datasource.watchman.jdbcUrl.adb=jdbc:mysql://A.mysql.rds.aliyuncs.com:3306/{db[1~20]} 
db.datasource.watchman.username.adb={A.db1:dw_datacenter_A,A.db2:dw_datacenter_B,A.db3:dw_datacenter_C,A.db...} db.datasource.watchman.password.adb= {A.db1:password_A,A.db2:password_B,A.db3:password_C,A.db...}

關于“怎么用Java設計實現多實例多庫查詢”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

天水市| 贵德县| 甘洛县| 广河县| 九寨沟县| 莱西市| 闵行区| 额济纳旗| 济宁市| 洪湖市| 固阳县| 无棣县| 元谋县| 宁晋县| 高唐县| 孝感市| 武山县| 西贡区| 温宿县| 清徐县| 家居| 长春市| 石家庄市| 铅山县| 霍林郭勒市| 北宁市| 肥东县| 镇江市| 崇礼县| 昂仁县| 松溪县| 阳高县| 上思县| 淮安市| 华宁县| 长沙县| 博乐市| 新昌县| 平远县| 盐池县| 诏安县|