MyCat的拆分原则,分片JOIN,拆分规则

拆分原则

1. 达到一定数量级才拆分(800 万)

2. 不到 800 万但跟大表(超 800 万的表)有关联查询的表也要拆分,在此称为大表关联表

3. 大表关联表如何拆:小于 100 万的使用全局表;大于 100 万小于 800 万跟大表使用同样的拆分策略;无法跟大表使用相同规则的,可以考虑从 java 代码上分步骤查询,不用关联查询,或者破例使用全局表。

4. 破例的全局表:如 item_sku 表 250 万,跟大表关联了,又无法跟大表使用相同拆分策略,也做成了全局表。破例的全局表必须满足的条件:没有太激烈的并发 update,如多线程同时 update 同一条 id=1 的记录。虽有多线程 update,但不是操作同一行记录的不在此列。多线程 update 全局表的同一行记录会死锁。批量 insert没问题。

5. 拆分字段是不可修改的

6. 拆分字段只能是一个字段,如果想按照两个字段拆分,必须新建一个冗余字段,冗余字段的值使用两个字段的值拼接而成(如大区+年月拼成 zone_yyyymm 字段)。

7. 拆分算法的选择和合理性评判:按照选定的算法拆分后每个库中单表不得超过 800 万

8. 能不拆的就尽量不拆。如果某个表不跟其他表关联查询,数据量又少,直接不拆分,使用单库即可。

分片JOIN

Join 绝对是关系型数据库中最常用一个特性,然而在分布式环境中,跨分片的 join 确是最复杂的,最难解决一个问题

mycat 支持跨分片join,主要有四种方法:全局表、ER 分片、catletT(人工智能)、ShareJoin
1、全局表
    数据规模不大,很少有超过数十万条记录可以做为全局表,少进行DML语句,但是数据不是必须的要小于十万条记录,根据情况而定
全局表具有以下特性:
1. 全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
2.全局表的查询操作,只从一个节点获取
3.全局表可以跟任何一个表进行 JOIN 操作
4.多线程update 可以不是同一条记录,如果多线程udpate 全局表同一条记录会出现死锁,批量insert 是可以的。

配置:
<table name="teacher" primaryKey="id" type="global" dataNode="dn1,dn2" />
全局表中的数据在所有分片上都一样,不用写rule拆分规则,对于全局表,所有的查询请求,只会发送到其中一个全局表分片上执行,所有的更新请求,会在每个全局表分片上执行。

Mycat 在 Join 操作中,业务表与全局表进行 Join 聚合会优先选择相同分片内的全局表 join,避免跨库 Join,在进行数据插入操作时,mycat 将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。

全局表就是做了数据冗余,保证各个分片上的数据一致,所以说要保证每个分片上的数据一致是必要的,不然会出现错误数据。
2、ER分片
    MyCAT 借鉴了 NewSQL 领域的新秀 Foundation DB 的设计思路,Foundation DB 创新性的提出了 Table 
Group 的概念,其将子表的存储位置依赖于主表,并且物理上紧邻存放,因此彻底解决了 JION 的效率和性能问题,根据这一思路,提出了基于 E-R 关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片,避免数据的JOIN跨库操作。
schema.xml 配置:
以teacher与student 为例,schema.xml 中定义如下分片配置,teacher、student 根据teacher的id进行数据分片,保证同一个teacher的id所关联的学生的tid的数据落到同一个分片上,在进行数据插入操作时,mycat会获取teacher所在在分片,然后将student也插入到teacher所在的分片,从而避免了跨库查询。

查询语句:select * from stu s join teacher t on s.tid=t.id;

<table name="teacher" primaryKey="id" autoIncrement="false" dataNode="dn1,dn2" rule="mod-long">
            <childTable name="stu" primaryKey="id" parentKey="id" joinKey="tid"/>
</table>

ER表的子表不支持批量插入ChildTable multi insert not provided,

ER表也叫父子表,父表的数据存在哪个分片上子表的数据就存在哪个分片上,从而避免了跨库查询,子表的分片规则是有父表来决定的,就算你给子表指定了分片规则但是该分片规则是不起作用的,这种情况会造成数据库子表的数据分布不均匀。为了保证关联查询的效率,这个也是无关紧要的!!

3、ShareJoin
    ShareJoin 是一个简单的跨分片 Join,基于 HBT 的方式实的。目前支持 2 个表的 join,原理就是解析 SQL 语句,拆分成单表的 SQL 语句执行,然后把各个节点的数据汇集。
两张表的规则可以任意配置,跨库查询也是没有问题的。

使用方式在sql语句前面加上注释:/*!mycat:catlet=io.mycat.catlets.ShareJoin*/select * from stu s join teacher t on s.tid=t.id;

4、catlet(人工智能)

    解决跨分片的 SQL JOIN 的问题,远比想象的复杂,而且往往无法实现高效的处理,既然如此,就依靠人工的智力,去编程解决业务系统中特定几个必须跨分片的 SQL 的 JOIN 逻辑,MyCAT 提供特定的 API 供程序员调用,这就是 MyCAT 创新性的思路——人工智能


Mcat 分片规则

分片规则概述

    在数据切分处理中,特别是水平切分中,中间件最终要的两个处理过程就是数据的切分、数据的聚合。选择合适的切分规则,至关重要,因为它决定了后续数据聚合的难易程度,甚至可以避免跨库的数据聚合处理。
多对多关联

    有一类业务场景是 “主表 A+关系表+主表 B”,举例来说就是商户会员+订单+商户,对应这类业务,如何切分?

    从会员的角度,  如果需要查询会员购买的订单,那按照会员进行切分即可,但是如果要查询商户当天售出的订单,那又需要按照商户做切分,可是如果既要按照会员又要按照商户切分,几乎是无法实现,这类业务如何选择切分规则非常难。目前还暂时无法很好支持这种模式下的 3 个表之间的关联。目前总的原则是需要从业务角度来看,关系表更偏向哪个表,即“A 的关系”还是“B 的关系”,来决定关系表跟从那个方向存储,未来 Mycat版本中将考虑将中间表进行双向复制,以实现从 A-关系表 以及 B-关系表的双向关联查询如下图所示:

 

主键分片 vs 非主键分片
    当你没人任何字段可以作为分片字段的时候,主键分片就是唯一选择,其优点是按照主键的查询最快,当采用自动增长的序列号作为主键时,还能比较均匀的将数据分片在不同的节点上。若有某个合适的业务字段比较合适作为分片字段,则建议采用此业务字段分片,选择分片字段的条件如下:
1、尽可能的比较均匀分布数捤到各个节点上

2、该业务字段是最频繁的或者最重要的查询条件。(因为条件带分片字段mycat不会扫描所有分片,可以通过explain查看sql执行的分片信息

3、常见的除了主键之外的其他可能分片字段有“订单创建时间”、“店铺类别”或“所在省”等。当你找到某个合适的业务字段作为分片字段以后,不必纠结于“牺牲了按主键查询记录的性能”,因为在这种情况下,MyCAT 提供了“主键到分片”的内存缓存机制,热点数据按照主键查询,丝毫不损失性能。

4、对于非主键分片的 table,填写属性 primaryKey,此时 MyCAT 会将你根据主键查询的 SQL 语句的第一次执行结果进行分析,确定该 Table 的某个主键在什么分片上,并进行主键到分片 ID 的缓存。第二次或后续查询mycat 会优先从缓存中查询是否有 id–>node 即主键到分片的映射,如果有直接查询,通过此种方法提高了非主键分片的查询性能。总之尽量规避跨库 Join 是一条最重要的原则,所以说选择符合业务的分片规则能最大化的避免跨库查询。


mycat 性能建议
1、尽量避免使用 Left join 或 Right join,而用 Inner join

2、在使用 Left join 或 Right join 时,ON 会优先执行,where 条件在最后执行,所以在使用过程中,条件尽可能的在 ON 语句中判断,减少 where 的执行

3、少用子查询,而用 join。

4、Mycat 目前版本支持跨分片的 join,主要实现的方式有四种。全局表,ER 分片,catletT(人工智能)和 ShareJoin,ShareJoin ,所以说选择好分片规则很重要,最大化的避免跨分片join。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值