数据库中间件tddl与mycat使用总结

做订单中心项目的时候正好涉及到了数据库中间件,翻了翻以前的笔记,整理下曾经学习使用过的两款中间件,嗯,简要总结下。

tddl是淘宝在几年前推出的一款基于客户端分片的数据库访问中间件,mycat(社区活跃)是开源社区基于服务端分片推出的数据库中间件,具体的介绍百度上都有,这里我主要根据自己的实际使用情况来总结下其异同以及优缺点:

1,基于客户端分片的方案应该是数据库分片方案中最快的,它以jar包的形式提供给客户端使用,没有中间件,仅需要客户端进行一次计算(如取模等),但这同样是其缺点,与业务端耦合了(不过tddl jar很轻量,应该还好)。还有个问题就是升级比较困难,如果jar升级了,需要挨个业务线去推动升级,可能阻力比较大,从该点看,tddl适合业务场景固定,功能变动可能性很小的地方

2,基于客户端的分片不需要额外的proxy,不需要关注proxy机器的部署和维护,对于mycat来说,多了代理层,需要自己做负载均衡方案,因为代理层不是无状态的。

3,tddl不能强制读主,需要自己开发这个功能,mycat提供了强制读主的hint

4,如果进行了读写分离,写完后立即要进行读操作,这时候从库可能还没有同步到数据,这种场景下是需要读主的,tddl不支持这种场景,需要自己开发,mycat提供了策略解决这个问题,如下:

Mycat 心跳机制通过检测 show slave status 中的 "Seconds_Behind_Master","Slave_IO_Running","Slave_SQL_Running",三个字段来确定当前主从同步的状态以及 Seconds_Behind_Master 主从复制时延。当 Seconds_Behind_Master > slaveThreshold 时,读写分离筛选器会过滤掉此 Slave 机器,防止读到很久之前的旧数据。

5,tddl和mycat都支持带有权重的读写分析操作

6,tddl以jar的方式提供访问,只能给java使用,mycat没有这个限制

7,mycat支持多个分片自动路由和聚合,tddl不支持,比如:select * from order,mycat会分发到所有的节点,然后将返回值进行聚合,所以诸如count,sum,max等函数在mycat下是支持的

8,join夸库连表查询tddl不支持,mycat可以跨库支持两个表的join(其实要想实现join,一种方式是采用caltlet,另一个中方式就是er分片了(这种方式下也不能算做支持跨库),还有就是全局表(这个方案是个冗余数据的方案,不具有可比性),如果纯粹像原来单库那样查询的话,会存在问题,见下面例子),多表的话要基于caltlet实现,需要自己开发,例子:

分库信息为db01,db02两个库,配置如下:

mod(2)方式分片,两张表travelrecord和user,首先在mycat中insert一条数据到travelrecord:

数据库中间件tddl与mycat使用总结_第1张图片

接下来insert两条数据到user:

数据库中间件tddl与mycat使用总结_第2张图片

然后执行sql:select * from travelrecord t join user u on u.travelrecord_id=t.id where t.id>1;得到如下结果:

可以看到满足条件的只有一条记录,这是应为traverecord_id=1054698916794208257只存在于一个分片上 。接下来我们采用er分片的方式,配置如下:

重新向两张表插入数据,最终结果如下:

数据库中间件tddl与mycat使用总结_第3张图片

这是由于在插入user的时候选择了与traverecord_id相同的分片,从这个角度看mycat实际上也不支持跨库join查询!!!最后我们来看下使用Catlet:

数据库中间件tddl与mycat使用总结_第4张图片

这个方案可以说算是真正支持跨库join的方案,它其实是会分成两条sql执行:

1,select *, id from travelrecord where id>1

2,select * from user where travelrecord_id in (1055292098535886849)

1055292098535886849为第一条sql的查出来的id,然后对结果进行聚合。

不过个人认为,既然都分片了,最好就不要在sql中使用join,想其他方案替代吧。如果一定要用的话,最好在生产应用前测试下使用Catlet方式的性能。

9, tddl支持既分库又分表,而mycat当前(1.6)还不支持(需要自己开发?),tddl的分库分表配置例子如下:


        
        
            
                ((int)(#user_id# /2))%2
            
        
        
            
                #user_id# % 2
            
        
        
        
    

上面的例子按照user_id/2%2进行分库,user_id%2进行分表

10,mycat默认提供了多种分片的方式,tddl的支持的分片方式有限(可自己改代码实现自己的分片方式)

11,tddl只支持单库事务,mycat号称支持分布式事务(支持有限,基于session),首先来看如下的事务操作(普通的begin,commit):

数据库中间件tddl与mycat使用总结_第5张图片

两个insert分别在两个节点上进行,mycat在执行begin时,会设置autocommit=false,在执行insert时传递过去,分别让两个节点执行insert,commit提交后,再分别在两个节点上执行commit。从这里我们可以看出来,如果其中任意一个节点commit时失败了,是没法回滚另一个节点的(已经成功commit)。至于xa协议,实际上是开启了mysql对xa的支持,mycat还是作为一个发号时令者,实际应用用的分布式事务需要采用专门的方案来解决,恩,比较少使用到xa。

12,tddl扩容时需要停机,修改配置文件,然后重启应用,mycat号称可以在线扩容(基于zk),不过我们没有使用过,以后如果有机会使用了再来补充

总之个人认为,在使用这些中间件时,需要根据你的业务场景,提取出涉及到的sql,看下实际执行中是否有问题(严格测试),如果无法支持得想替代方案或者改源码。

其他特性或者功能目前本人也没有用过,以后如果有用到后再来补充。

 

 

 

 

你可能感兴趣的:(分布式系统,个人工作中的总结)