Mycat跨分片Join
1 前言
Mycat目前版本支持跨分片的join,主要实现的方式有四种。
全局表
ER分片
HBT(参考MyCAT人工智能解决跨分片SQL.docx)
ShareJoin
ShareJoin在开发版中支持,前面三种方式1.3.0.1支持
2 ShareJoin
ShareJoin是一个简单的跨分片Join,基于HBT的方式实现。
目前支持2个表的join,原理就是解析SQL语句,拆分成单表的SQL语句执行,然后把各个节点的数据汇集。
支持任意配置的A,B表
如:
A,B的dataNode相同
<table name="A" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<table name="B" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
A,B的dataNode不同
<table name="A" dataNode="dn1,dn2 " rule="auto-sharding-long" />
<table name="B" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
或
<table name="A" dataNode="dn1 " rule="auto-sharding-long" />
<table name="B" dataNode=" dn2,dn3" rule="auto-sharding-long" />
2.1相关类图
JoinParser: SQL语句的解析
TableFilter:存解析后的各个子表
ShareJoin:执行拆分的语句管理控制,和字段,记录的管理
ShareDBJoinHandler:第一个表执行后获取数据的handler
ShareRowOutPutDataHandler:最后一个表执行后获取数据的handler
EnginerCtx:执行引擎
SQLJob:SQL语句执行任务
SQLJobHandler:SQL语句执行后获取数据的handler
BatchSQLJob:批量执行任务控制
AllJobFinishedListener:所有任务完成侦听器
RouteService-----》HintCatletHandler---》ShareJoin
2.1测试
默认mycat的环境测试:
/*!mycat:catlet=demo.catlets.ShareJoin */ select a.*,b.id, b.name as tit from customer a,company b on a.company_id=b.id;
/*!mycat:catlet=demo.catlets.ShareJoin */ select a.*,b.id, b.name as name from orders a join customer b where a.customer_id=b.id;
/*!mycat:catlet=demo.catlets.ShareJoin */ select a.*,b.* from orders a join customer b where a.customer_id=b.id;
/*!mycat:catlet=demo.catlets.ShareJoin */ select a.id,a.user_id,a.traveldate,a.fee,a.days,b.id as nnid, b.title as tit from travelrecord a join hotnews b on b.id=a.days order by a.id ;
2.3升级
未来支持多表的跨分片Join
小表放人缓存或广播方式
3全局表
一个真实的业务系统中,往往存在大量的类似字典表的表格,它们与业务表之间可能有关系,这种关系,可以理解为“标签”,而不应理解为通常的“主从关系”,这些表基本上很少变动,可以根据主键ID进行缓存,下面这张图说明了一个典型的“标签关系”图:
在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,考虑到字典表具有以下几个特性:
- 变动不频繁
- 数据量总体变化不大
- 数据规模不大,很少有超过数十万条记录。
鉴于此,MyCAT定义了一种特殊的表,称之为“全局表”,全局表具有以下特性:
- 全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
- 全局表的查询操作,只从一个节点获取
- 全局表可以跟任何一个表进行JOIN操作
将字典表或者符合字典表特性的一些表定义为全局表,则从另外一个方面,很好的解决了数据JOIN的难题。通过全局表+基于E-R关系的分片策略,MyCAT可以满足80%以上的企业应用开发。
3.1配置
全局表配置比较简单,不用写Rule规则,如下配置即可:
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
需要注意的是,全局表每个分片节点上都要有运行创建表的DDL语句。
4ER分片
MyCAT借鉴了NewSQL领域的新秀Foundation DB的设计思路,Foundation DB创新性的提出了Table Group的概念,其将子表的存储位置依赖于主表,并且物理上紧邻存放,因此彻底解决了JION的效率和性能问题,根据这一思路,提出了基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上。
customer采用sharding-by-intfile这个分片策略,分片在dn1,dn2上,orders依赖父表进行分片,两个表的关联关系为orders.customer_id=customer.id。于是数据分片和存储的示意图如下:
这样一来,分片Dn1上的的customer与Dn1上的orders就可以进行局部的JOIN联合,Dn2上也如此,再合并两个节点的数据即可完成整体的JOIN,试想一下,每个分片上orders表有100万条,则10个分片就有1个亿,基于E-R映射的数据分片模式,基本上解决了80%以上的企业应用所面临的问题。
4.1 配置
以上述例子为例,schema.xml中定义如下的分片配置:
<table name="customer" dataNode="dn1,dn2" rule="sharding-by-intfile">
<childTable name="orders" joinKey="customer_id" parentKey="id"/>
</table>
5HBT分片
解决跨分片的SQL JOIN的问题,远比想象的复杂,而且往往无法实现高效的处理,既然如此,就依靠人工的智力,去编程解决业务系统中特定几个必须跨分片的SQL的JOIN逻辑,MyCAT提供特定的API供程序员调用,这就是MyCAT创新性的思路——人工智能。
以一个跨节点的SQL为例,
Select a.id,a.name,b.title from a,b where a.id=b.id
其中a在分片1,2,3上,b在4,5,6上,需要把数据全部拉到本地(MyCAT服务器),执行JOIN逻辑,具体过程如下(只是一种可能的执行逻辑):
EngineCtx ctx=new EngineCtx();//包含MyCat.SQLEngine
String sql=,“select a.id ,a.name from a ”;
//在a表所在的所有分片上顺序执行下面的本地SQL
ctx.executeNativeSQLSequnceJob(allAnodes,new DirectDBJoinHandler());
DirectDBJoinHandler类是一个回调类,负责处理SQL执行过程中返回的数据包,这里的这个类,主要目的是用a表返回的ID信息,去b表上查询对于的记录,做实时的关联:
DirectDBJoinHandler{
Private HashMap<byte[],byte[]> rows;//Key为id,value为一行记录的Column原始Byte数组,这里是a.id,a.name,b.title这三个要输出的字段
Public Boolean onHeader(byte[] header)
{
//保存Header信息,用于从Row中获取Field字段值
}
Public Boolean onRowData(byte[] rowData)
{
String id=getColumnAsString(“id”);
//放入结果集,b.title字段未知,所以先空着
rows.put(getColumnRawBytes(“id”),rowData);
//满1000条,发送一个查询请求
String sql=”select b.id, b.name from b where id in (………….)”;
//此SQL在B的所有节点上并发执行,返回的结果直接输出到客户端
ctx.executeNativeSQLParallJob(allBNodes,sql ,new MyRowOutPutDataHandler(rows));
}
Public Boolean onRowFinished()
{
}
Public void onJobFinished()
{
If(ctx.allJobFinished())
{///used total time ….
}
}
}
/最后,增加一个Job事件监听器,这里是所有Job完成后,往客户端发送RowEnd包,结束整个流程。
ctx.setJobEventListener(new JobEventHandler(){public void onJobFinished(){ client.writeRowEndPackage()}});
以上提供一个SQL执行框架,完全是异步的模式执行,并且以后会提供更多高质量的API,简化分布式数据处理,比如内存结合文件的数据JOIN算法,分组算法,排序算法等等,
期待更多的牛人一起来完善。
Mycat跨分片Join的更多相关文章
- Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用
一.Mycat和Sharding-jdbc的区别 1)mycat是一个中间件的第三方应用,sharding-jdbc是一个jar包 2)使用mycat时不需要改代码,而使用sharding-jdbc时 ...
- MyCat 枚举分片设计思考,查询命中条件
Mycat多租户实现的两种方式 MyCat,各种分片规则,仅保证插入的时候分片.表关联,join,查询怎么命中分片条件,还是需要设计. 今天稍微测了一下. ER 分片,此方式,插入的时候能分片,但是查 ...
- 分库分表后跨分片查询与Elastic Search
携程酒店订单Elastic Search实战:http://www.lvesu.com/blog/main/cms-610.html 为什么分库分表后不建议跨分片查询:https://www.jian ...
- JAVAEE——宜立方商城13:Mycat数据库分片、主从复制、读写分离、100%Linux中成功安装Mysql的方法
1 海量数据的存储问题 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求.这个时候NoSQL ...
- JAVAEE——宜立方商城13:订单系统实现、订单生成、Mycat数据库分片
1. 学习计划 1.订单系统实现 2.订单生成 3.Mycat数据库分片 2. 订单系统 2.1. 功能分析 1.在购物车页面点击“去结算”按钮,跳转到订单确认页面 a) 必须要求用户登录 b) 使用 ...
- mycat 分页慢原理解析、mycat跨事务解惑、mycat注解调用存储过程分析
1结合Mycat日志,分析select * from travelrecord order by id limit100000,100 的运行过程,解释下当limit M,N中的M非常大的情况下.为什 ...
- 实现数据库的跨库join
功能需求 首先要理解原始需求是什么,为什么要跨库join.举个简单的例子,在日志数据库log_db有一份充值记录表pay_log,里面的用户信息只有一个userid:而用户的详细信息放在主库main_ ...
- RChain的跨分片交易算法
跨分片交易是一个难题,但是遗憾的是业界已经有一个项目RChain解决了这个问题. 分片方式有很多种,最难的是状态分片,什么是状态分片呢?把以太坊比作银行的话,状态指的是银行账户的当前余额.那状态分片就 ...
- Mysql系列六:(Mycat分片路由原理、Mycat常用分片规则及对应源码介绍)
一.Mycat分片路由原理 我们先来看下面的一个SQL在Mycat里面是如何执行的: , ); 有3个分片dn1,dn2,dn3, id=5000001这条数据在dn2上,id=10000001这条数 ...
随机推荐
- JavaScript 操作JSON总结
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...
- 647. Palindromic Substrings(马拉车算法)
问题 求一个字符串有多少个回文子串 Input: "abc" Output: 3 Input: "aaa" Output: 6 思路和代码(1)--朴素做法 用 ...
- 利用arcgis制作出 源解析要用的ASCII文件
准备:1.确定好模拟区域范围,精度,行列数 2.确定好源解析的城市规划 思路: 1.全国省级图+本地市县图-->合成一张区域图(联合) 合成之后,添加一个字段,一个数字类型字段 ...
- Django学习笔记之django-debug-toolbar使用指南
介绍 django-debug-toolbar 是一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息. github地址 文档地址 安装 pip3 in ...
- oracle错误一览表
ORA-00001: 违反唯一约束条件 (.)ORA-00017: 请求会话以设置跟踪事件ORA-00018: 超出最大会话数ORA-00019: 超出最大会话许可数ORA-00020: 超出最大进程 ...
- 20145303 《Java程序设计》第六周学习总结
20145303 <Java程序设计>第六周学习总结 教材学习内容总结 第十章:输入/输出 (InputStream与OutputStream) 1.Java将输入/输出抽象化为串流,数据 ...
- 轻谈Normalize.css
Normalize.css 是 * ? Normalize.css只是一个很小的CSS文件,但它在默认的HTML元素样式上提供了跨浏览器的高度一致性.相比于传统的CSS reset , Normali ...
- 将应用注册为Linux的服务
主流的Linux大多使用init.d或systemd来注册服务.下面以centos6.6演示init.d注册服务:以centos7.1演示systemd注册服务. 1. 基于Linux的init.d部 ...
- 正则表达式-RegExp-常用正则表达式
正则表达式-RegExp-常用正则表达式 作者:nuysoft/JS攻城师/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源 ...
- 使用js合并table中的单元格
用primefaces做的报表,领导要求合并相同内容的单元格,但是primefaces没有找到可以合并单元格的组件,想来想去,只有页面加载后用js合并了. http://blog.csdn.net/d ...