专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Mycat分表的原理是什么

Mycat分表的原理是什么

更新时间:2021-06-15 16:21:04 来源:动力节点 浏览1146次

MyCat适应于那些场景

数据量大到单机hold不住,而又不希望调整架构切换为NoSQL数据库,这个场景下可以考虑适用mycat。当然,使用前也应该做规划,哪些表需要分片等等。另外mycat对跨库join的支持不是很好,在使用mycat的时候要注意规避这种场景。其实不至这一种方式,还有其他的一些数据库中间件。比如说TIDB或者是shardingsphere。shardingsphere没有使用过,但是TIDB的的确确可以用于生产环境。

非分片字段查询

MyCat中的路由结果是通过分片字段和分片方法来确定的。例如下图中的MyCat分库方案

根据tt_waybill表的id字段来进行分片

分片方法为id值取3的模,根据模值确定在DB1,DB2,DB3中的某个分片

mycat分表

如果查询条件中有 id 字段的情况还好,查询将会落到某个具体的分片。例如:

mysql>select * from tt_waybill where id = 12330;

此时Mycat会计算路由结果

12330 % 3 = 0 –> DB1

并将该请求路由到DB1上去执行。 


如果查询条件中没有 分片字段 条件,例如:

mysql>select * from tt_waybill where waybill_no =88661;

此时Mycat无法计算路由,便发送到所有节点上执行:

DB1 –> select * from tt_waybill where waybill_no =88661; 
DB2 –> select * from tt_waybill where waybill_no =88661; 
DB3 –> select * from tt_waybill where waybill_no =88661;

如果该分片字段选择度高,也是业务常用的查询维度,一般只有一个或极少数个DB节点命中(返回结果集)。示例中只有3个DB节点,而实际应用中的DB节点数远超过这个,假如有50个,那么前端的一个查询,落到MySQL数据库上则变成50个查询,会极大消耗Mycat和MySQL数据库资源。如果设计使用Mycat时有非分片字段查询,请考虑放弃!

分页排序

先看一下Mycat是如何处理分页操作的,假如有如下Mycat分库方案:一张表有30份数据分布在3个分片DB上,具体数据分布如下:

DB1:[0,1,2,3,4,10,11,12,13,14]

DB2:[5,6,7,8,9,16,17,18,19]

DB3:[20,21,22,23,24,25,26,27,28,29]

mycat分表

当应用执行如下分页查询时

mysql>select * from table limit 2;

Mycat将该SQL请求分发到各个DB节点去执行,并接收各个DB节点的返回结果

DB1: [0,1] 
DB2: [5,6] 
DB3: [20,21]

但Mycat向应用返回的结果集取决于哪个DB节点最先返回结果给Mycat。如果Mycat最先收到DB1节点的结果集,那么Mycat返回给应用端的结果集为[0,1],如果Mycat最先收到DB2节点的结果集,那么返回给应用端的结果集为[5,6]。也就是说,相同情况下,同一个SQL,在Mycat上执行时会有不同的返回结果。

在Mycat中执行分页操作时必须显示加上排序条件才能保证结果的正确性,下面看一下Mycat对排序分页的处理逻辑。

假如在前面的分页查询中加上了排序条件(假如表数据的列名为id)。比如如下所示:

	mysql>select * from table order by id limit 2;

mycat分表

在有排序的条件的情况下,Mycat接收到各个DB节点的返回结果后,对其进行最小堆运算,计算出所有结果集中最小的两条记录 [0,1] 返回给应用。但是,当排序分页中有 偏移量 (offset)时,处理逻辑又有不同。假如应用的查询SQL如下:

mysql>select * from table order by id limit 5,2;

mycat分表

Mycat将各个DB节点返回的数据[10,11],[16,17],[20,21]经过最小堆计算后返回给应用的结果集是[10,11]。可是,对于应用而言,该表的所有数据明明是0-29这30个数据的集合,limit 5,2操作返回的结果集应该是[5,6],如果返回[10,11]则是错误的处理逻辑。所以Mycat在处理有偏移量的排序分页时是另外一套逻辑——改写SQL。如下图:

mycat分表

MyCat在下发有 limit m,n 的SQL语句时会对其进行改写,改写成 limit 0, m+n 来保证查询结果的逻辑正确性。所以,Mycat发送到后端DB上的SQL语句是:

mysql>select * from table order by id limit 0,7;
各个DB返回给Mycat的结果集是

DB1: [0,1,2,3,4,10,11] 
DB2: [5,6,7,8,9,16,17] 
DB3: [20,21,22,23,24,25,26]
经过最小堆计算后得到最小序列 [0,1,2,3,4,5,6] ,然后返回偏移量为5的两个结果为 [5,6] 。

虽然Mycat返回了正确的结果,但是仔细推敲发现这类操作的处理逻辑是及其消耗(浪费)资源的。应用需要的结果集为2条,Mycat中需要处理的结果数为21条。也就是说,对于有t个DB节点的全分片limit m,n操作,Mycat需要处理的数据量为(m+n)*t个。比如实际应用中有50个DB节点,要执行limit 1000,10操作,则Mycat处理的数据量为50500条,返回结果集为10,当偏移量更大时,内存和CPU资源的消耗则是数十倍增加。如果设计使用MyCat时有分页排序,请考虑放弃!

以上就是动力节点Java培训机构的小编针对“Mycat分表的原理是什么”的内容进行的回答,希望对大家有所帮助,如有疑问,请在线咨询,有专业老师随时为你服务。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>