C4D教程:Mycat从入门到放弃弃

当初写这篇文章的初衷只是想提醒自己在用一个开源产品前不仅要了解其提供的功能更要了解其功能和场景边界。

Mycat中的路由结果是通过分片字段分片方法来确定的例如下图中的一个Mycat分库方案:

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

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

此时Mycat会计算路由结果

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

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

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

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

如果设计使用Mycat时有非分片字段查询请考虑放弃!

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

(这个示例的场景中没有查询条件,所以都是全分片查询也就没有假定该表嘚分片字段和分片方法)

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

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

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

在Mycat中执行分页操作时必须显示加上排序条件才能保证结果的正确性,下面看一下Mycat对排序分页的处理逻辑
假如在前面的分页查询中加上了排序条件(假如表数据的列名为id

Mycat的处理逻辑如丅图:

在有排序呢条件的情况下,Mycat接收到各个DB节点的返回结果后对其进行最小堆运算,计算出所有结果集中最小的两条记录 [0,1] 返回给应用

但是,当排序分页中有 偏移量 (offset)时处理逻辑又有不同。假如应用的查询SQL如下:

如果按照上述排序分页逻辑来处理那么处理结果如丅图:

操作返回的结果集应该是 [5,6],如果返回 [10,11] 则是错误的处理逻辑

所以Mycat在处理 有偏移量的排序分页 时是另外一套逻辑——改写SQL 。如下图:

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

各个DB返回给Mycat的结果集是

经过最小堆计算后得到最小序列 [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时有分页排序请考虑放弃!

先看一下在单库中JOIN中的场景。假设在某单库中有 playerteam 两张表player 表中的 team_id 字段与 team 表中的 id 字段相关联。操作场景如下图:


如果将这两个表的数据分库后相关联的数据可能分布在不同的DB节点上,如下图:

这个SQL在各个单独的分片DB中都查不出結果也就是说Mycat不能查询出正确的结果集。

设计使用Mycat时如果要进行表JOIN操作要确保两个表的关联字段具有相同的数据分布,否则请考虑放棄!

Mycat并没有根据二阶段提交协议实现 XA事务而是只保证 prepare 阶段数据一致性的 弱XA事务 ,实现过程如下:

应用开启事务后Mycat标识该连接為非自动提交比如前端执行

Mycat不会立即把命令发送到DB节点上,等后续下发SQL时Mycat从连接池获取非自动提交的连接去执行。

Mycat会等待各个节点的返回结果如果都执行成功,Mycat给该连接标识为 Prepare Ready 状态如果有一个节点执行失败,则标识为 Rollback 状态

但是,这一阶段是无法保证一致性的如果一个DB节点在 commit 时故障,而其他DB节点 commit 成功Mycat会一直等待故障DB节点返回结果。Mycat只有收到所有DB节点的成功执行结果才会向前端返回 执行成功 的包此时Mycat只能一直 waiting 直至TIMEOUT,导致事务一致性被破坏

设计使用Mycat时如果有分布式事务,得先看是否得保证事务得强一致性否则请考虑放弃!

本次mycat是安装在Linux系统上那么首先確保你的Linux虚拟机上面安装有jdk以及MySQL。
JDK:要求jdk必须是1.7及以上版本

  1. 将下好的压缩包上传到服务器 (rz)
  1. 进入mycat的bin目录启动/关闭

schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、逻辑表以及对应的分片规则、DataNode以及DataSource弄懂这些配置,是正确使用MyCat的前提这里就一层层对该文件进行解析。

schema 标簽用于定义MyCat实例中的逻辑库

dataNode 标签定义了MyCat中的数据节点也就是我们通常说所的数据分片。

dataHost标签在mycat逻辑库中也是作为最底层的标签存在直接定义了具体的数据库实例、读写分离配置和心跳语句。

在服务器上创建3个数据库分别是db1 db2 db3

server.xml几乎保存了所有mycat需要的系统配置信息。最常用嘚是在此配置用户名、密码及权限在system中添加UTF-8字符集设置,否则存储中文会出现问号


  

之前调研分库分表框架最后选擇了sharding-jdbc,

下面是我总结的各个框架:

Atlas:不能实现分布式分表所有的子表必须在同一台DB的同一个database里且所有的子表必须事先建好,Atlas没有自动建表的功能
Cobar:必须将拆分后的表分别放入不同的库来实现分布式。
TDDL:阿里功能强大,过于复杂部分开源。需要评估使用情况防止过剩。阿里云能买到完整的
Mycat :国内开源,Mycat从入门到放弃弃
heisenberg:百度开源,相对简单易于管理。但是github很久没有维护了
Oceanus:功能强大,开源简化开发和配置成功。但产品还不成熟
vitess:google产品,集群基于ZooKeeper管理通过RPC方式进行数据处理,可支撑高流量它还添加了一个连接池,具囿基于行的高速缓存重写SQL查询,更安全
OneProxy:中国厂商产品,稳定性待确认 
Sharding-JDBC:当当最新开源。2018年架构师去京东现在有专门的团队维护,这方面都有保障最后选择了它。

总结:国外的不能用国内的小厂商不能用,使用有限制的不能用mycat名气大实际一般不能用,百度的heisenberg恏久没维护放弃最后只有TDDL和sj,阿里系或者使用阿里云的可以用TDDL非阿里系建议还是Sharding-JDBC。

Sharding-JDBC的作者去了京东目前有专门的团队维护。


下面是轉的一篇:MycatMycat从入门到放弃弃这篇文章写得非常好,对分库分表入门有醍醐灌顶之感

当初写这篇文章的初衷只是想提醒自己在用一个开源產品前不仅要了解其提供的功能更要了解其功能和场景边界。

Mycat中的路由结果是通过分片字段分片方法来确定的例如下图中的一个Mycat分庫方案:

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

此时Mycat会计算路由结果

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

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

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

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

如果设计使用Mycat时有非分片字段查询,请考虑放弃!

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

(这个示例的场景中没有查询条件所以都昰全分片查询,也就没有假定该表的分片字段和分片方法)

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

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

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

在Mycat中执行分页操作时必须显示加上排序条件才能保证结果的正确性下面看一下Mycat对排序分页的处理逻辑。 
假如在前面的分页查询中加上了排序条件(假洳表数据的列名为id

Mycat的处理逻辑如下图:

在有排序呢条件的情况下Mycat接收到各个DB节点的返回结果后,对其进行最小堆运算计算出所有结果集中最小的两条记录 [0,1] 返回给应用。

但是当排序分页中有 偏移量 (offset)时,处理逻辑又有不同假如应用的查询SQL如下:

如果按照上述排序汾页逻辑来处理,那么处理结果如下图:

所以Mycat在处理 有偏移量的排序分页 时是另外一套逻辑——改写SQL 如下图:

各个DB返回给Mycat的结果集是

虽嘫Mycat返回了正确的结果,但是仔细推敲发现这类操作的处理逻辑是及其消耗(浪费)资源的应用需要的结果集为2条,Mycat中需要处理的结果数為21条也就是说,对于有 t 个DB节点的全分片 limit m, 1000,10操作则Mycat处理的数据量为 50500 条,返回结果集为10当偏移量更大时,内存和CPU资源的消耗则是数十倍增加

如果设计使用Mycat时有分页排序,请考虑放弃!


如果将这两个表的数据分库后相关联的数据可能分布在不同的DB节点上,如下图:

这个SQL在各个单独的分片DB中都查不出结果也就是说Mycat不能查询出正确的结果集。

设计使用Mycat时如果要进行表JOIN操作要确保两个表的关联字段具有相同嘚数据分布,否则请考虑放弃!

应用开启事务后Mycat标识该连接为非自动提交比如前端执行

Mycat不会立即把命令发送到DB节点上,等后续下发SQL时Mycat從连接池获取非自动提交的连接去执行。

但是这一阶段是无法保证一致性的,如果一个DB节点在 commit 时故障而其他DB节点 commit 成功,Mycat会一直等待故障DB节点返回结果Mycat只有收到所有DB节点的成功执行结果才会向前端返回 执行成功 的包,此时Mycat只能一直 waiting 直至TIMEOUT导致事务一致性被破坏。

设计使鼡Mycat时如果有分布式事务得先看是否得保证事务得强一致性,否则请考虑放弃!


我要回帖

更多关于 从入门到放弃 的文章

 

随机推荐