更新时间:2021-06-15 16:21:04 来源:极悦 浏览1274次
数据量大到单机hold不住,而又不希望调整架构切换为NoSQL数据库,这个场景下可以考虑适用mycat。当然,使用前也应该做规划,哪些表需要分片等等。另外mycat对跨库join的支持不是很好,在使用mycat的时候要注意规避这种场景。其实不至这一种方式,还有其他的一些数据库中间件。比如说TIDB或者是shardingsphere。shardingsphere没有使用过,但是TIDB的的确确可以用于生产环境。
MyCat中的路由结果是通过分片字段和分片方法来确定的。例如下图中的MyCat分库方案
根据tt_waybill表的id字段来进行分片
分片方法为id值取3的模,根据模值确定在DB1,DB2,DB3中的某个分片
如果查询条件中有 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]
当应用执行如下分页查询时
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接收到各个DB节点的返回结果后,对其进行最小堆运算,计算出所有结果集中最小的两条记录 [0,1] 返回给应用。但是,当排序分页中有 偏移量 (offset)时,处理逻辑又有不同。假如应用的查询SQL如下:
mysql>select * from table order by id limit 5,2;
Mycat将各个DB节点返回的数据[10,11],[16,17],[20,21]经过最小堆计算后返回给应用的结果集是[10,11]。可是,对于应用而言,该表的所有数据明明是0-29这30个数据的集合,limit 5,2操作返回的结果集应该是[5,6],如果返回[10,11]则是错误的处理逻辑。所以Mycat在处理有偏移量的排序分页时是另外一套逻辑——改写SQL。如下图:
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时有分页排序,请考虑放弃!
以上就是极悦注册机构的小编针对“Mycat分表的原理是什么”的内容进行的回答,希望对大家有所帮助,如有疑问,请在线咨询,有专业老师随时为你服务。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习