返回顶部
首页 > 资讯 > 精选 >怎么用Java设计实现多实例多库查询
  • 562
分享到

怎么用Java设计实现多实例多库查询

2023-07-05 12:07:37 562人浏览 泡泡鱼
摘要

这篇文章主要介绍“怎么用Java设计实现多实例多库查询”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用Java设计实现多实例多库查询”文章能帮助大家解决问题。服务的边界职责 大数据层取

这篇文章主要介绍“怎么用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设计实现多实例多库查询”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: 怎么用Java设计实现多实例多库查询

本文链接: https://lsjlt.com/news/351723.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么用Java设计实现多实例多库查询
    这篇文章主要介绍“怎么用Java设计实现多实例多库查询”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用Java设计实现多实例多库查询”文章能帮助大家解决问题。服务的边界职责 大数据层取...
    99+
    2023-07-05
  • sqlserver 中怎么使用sp_addlinkedserver实现多库查询
    sqlserver 中怎么使用sp_addlinkedserver实现多库查询 ,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。...
    99+
    2024-04-02
  • MySQL数据库查询中怎么实现多表查询
    今天小编给大家分享一下MySQL数据库查询中怎么实现多表查询的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、多表查询多表查...
    99+
    2023-06-29
  • Oracle如何实现多库查询
    这篇文章主要为大家展示了“Oracle如何实现多库查询”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Oracle如何实现多库查询”这篇文章吧。1.配置本地数据库...
    99+
    2024-04-02
  • mysql怎么实现多表查询
    这篇文章给大家分享的是有关mysql怎么实现多表查询的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、说明查询其实就是对于对于各个表格进行递归调用,和矩阵的乘法一样一样的,这个对应非常直观,也非常通用。常规的查询...
    99+
    2023-06-15
  • jdbc怎么实现多表查询
    JDBC是一种用于Java程序与数据库进行交互的API,它本身并不直接支持多表查询,而是提供了一些基本的数据库操作方法,如连接数据库...
    99+
    2023-10-30
    jdbc
  • mongoDB数据库中的多条件查询怎么利用Java实现
    mongoDB数据库中的多条件查询怎么利用Java实现?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。客户端代码:db.url.find({index:4,status:0,ur...
    99+
    2023-05-31
    java mongodb ava
  • MyBatis中怎么实现一对多查询和多对一查询
    这篇“MyBatis中怎么实现一对多查询和多对一查询”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MyBatis中怎么实现一...
    99+
    2023-06-29
  • java多级菜单模糊查询怎么实现
    要实现 Java 多级菜单的模糊查询,可以使用递归的方式来遍历菜单结构,然后根据输入的关键词来筛选匹配的菜单项。 以下是一个简单的示...
    99+
    2024-03-13
    java
  • Sqlite多列多层嵌套查询怎么实现
    在SQLite中进行多列多层嵌套查询,可以使用子查询或者连接操作来实现。以下是一个示例: 假设我们有两个表,一个是学生表studen...
    99+
    2024-04-11
    Sqlite
  • linq中怎么实现多表查询
    这篇文章给大家介绍linq中怎么实现多表查询,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1:1关系的多表操作表结构如上首先是测试取全记录的情况(也就是取所有字段)linq多表查询之直接写表达式var use...
    99+
    2023-06-17
  • layui多条件查询怎么实现
    在Layui中实现多条件查询可以通过以下步骤实现:1. 在HTML页面中创建一个表单,包含多个输入框或下拉框,用于用户输入查询条件。...
    99+
    2023-09-22
    layui
  • mongodb多条件查询怎么实现
    在 MongoDB 中,可以使用 $and、$or 等逻辑运算符来实现多条件查询。以下是使用 $and 运算符实现多条件查询的示例:...
    99+
    2024-04-10
    mongodb
  • Java 多输入框查询需求实现
    💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 多输入框查询 需求分析 任意一个输入框,输...
    99+
    2023-10-06
    java 开发语言
  • SQL中怎么实现多条件查询
    SQL中怎么实现多条件查询,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。第一种写法是if (@addDate is&n...
    99+
    2024-04-02
  • Hibernate中的多表查询怎么实现
    本篇内容介绍了“Hibernate中的多表查询怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、 Hibernate简介Hibern...
    99+
    2023-06-17
  • linq to sql多表查询怎么实现
    这篇文章主要讲解了“linq to sql多表查询怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“linq to sql多表查询怎么实现”吧!在手写sql的年代,如果想从sqlserv...
    99+
    2023-06-17
  • Linq中怎么实现多条件查询
    这篇文章将为大家详细讲解有关Linq中怎么实现多条件查询,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Linq多条件查询(高级搜索),假如一共可以输入5个条件,但是用户根据需要可能只输2个或...
    99+
    2023-06-17
  • Hibernate多表关联查询怎么实现
    本篇内容介绍了“Hibernate多表关联查询怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、Hibernate简介Hiberna...
    99+
    2023-06-17
  • Mariadb怎么实现多表连接查询
    这篇文章主要介绍“Mariadb怎么实现多表连接查询”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Mariadb怎么实现多表连接查询”文章能帮助大家解决问题。概念因为我们使用的是关系型数据库,每张表...
    99+
    2023-06-27
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作