开源的分布式数据库中间件系统Mycat和阿里巴巴Cobar的对比

mycat 不得不说的缘分

原创 2016年04月15日 15:48:17
  • 27834

                                 


1,愕然回首,它在灯火阑珊处

关于mysql集群中间件,以前写在应用程序里面,由开发人员实现,在配置文件里面写多个数据源,写库一个数据源,读库一个数据源,笨拙不高效,由于程序员的差异化,效果并不是特别理想。

 

后来,组织了开发人员写了一个自动识别读写的功能模块接口,让开发人员调用,这样能满足特定场景的业务需求,但是适应性比较窄。

 

后来出了cobar,但是在高并发这里出壳了,后来在一次无意中的演讲中,见到leader在介绍了mycat,于是眼前一亮,就是它了,不早不晚,在我特别需要的时候,就进入了我的生活。

 

2,人约黄昏后,月上柳梢头

记得leader说过,看百集非诚勿扰记千句乐嘉恋爱宝典,不如妹子约起……

 

万事开头难,兴趣攻其艰—>由于喜欢所以自然而然开始学习mycat,途中也认识了很多mycat的同道门,众所周知,对于我们这些非科班出生的,而且对理论研究不是那么深入的,实践永远是最好的最有效率的学习途径。

 

于是有了第一次,还蛮简单快捷方便的,从下载到安装然后试用,大概不到30分钟吧,如笔记所记录:

 

mycat - 解开它神秘的面纱--:http://blog.csdn.net/mchdba/article/details/51155340                                                                                                                                                           

 

 

 

之后马上做了第一个练习,mycat路由转发原理深度解析,对于此的理解是,mycat接到应用端过来的sql,它会去根据sql中 from后面的表名字,去配置schema.xml里面读取其中的所有datanode资源,然后一个个去路由去尝试请求,详情见我的blog整理:

 

Mycat路由转发原理深度解析:http://blog.csdn.net/mchdba/article/details/50616527                                                                                                                                                           

 

 

 

疑惑:如果做过数据库的缓存或者对mysqllimit有印象的话,应该记得有这样的场景,当limit 找到记录后,就exit不会继续遍历下面未遍历的数据记录了。不知道mycat是否可以做到这一点?貌似看debug日志是遍历了所有的datenode节点了。

 

PS:做这2个我还是得心应手,因为有linux基础,有mysql基础,所以算是比较顺利,好的开头是成功的一半,更加坚信自己的信心和选择了。

 


3,无奈是分离,victor大神

接下来开始接触mycat比较show time的部分了,读写分离和主从切换,对于这2个场景,我接触的时间蛮久了,但是实现的方式方法多种多样,以前读写分离用原始的刀耕火种,开发人员在ibatis/mybatis里面写死了写库连接和读库连接,之后keepalived+lvs,再之后用了f5的vip负载均衡配置,f5性能固然比较好,但是费用费用也不少的,所以对于互联网已经中小型公司来说,这笔支出可不实惠啊。

 

而mycat通过配置readHost和writeHost来实现读写分离,里面有一些配置,比如:

balance为1:让全部的readHost及备用的writeHost参与select的负载均衡。 
switchType为2:基于MySQL主从同步的状态决定是否切换。 
heartbeat:主从切换的心跳语句必须为show slave status

 

在这里遇到配置的时候,遇到一些问题,在请教了victor大神之后,他给了我他的实现思路和方法,我参考之后,顺利解决了,把自己这部分的学习整理成了笔记,如下:

 

mycat读写分离与主从切换:http://blog.csdn.net/mchdba/article/details/50616534                                                                                                                                                     

 

 

PS:想要victor大神的联系方式吗,在下面留言评论区,留下你的email地址并标注victor,我发你email告诉你的。

 

blog源地址:http://blog.csdn.net/mchdba/article/details/51162243谢绝转载。


4,庖丁血牛之mycat的黑匣子

 

对于mycat来说,打开debug这个帕朵拉魔盒,一切一切真相都暴露在大众面前,在这里你可以看到select的整个舞蹈轨迹,也可以看到所有的字符集的变换,千人千面万般操作尽在mycat.log。所以学会分析mycat.log日志,所有的问题都不再是问题,对于此我深有体会,如下的整理:

 

Mycat黑匣子:http://blog.csdn.net/mchdba/article/details/51160495                                                                                                                                                                            

 

 

 

5,分纷纷,生活的主旋律

分析了mycat的黑匣子后,对于mycat背后的逻辑以及有了一定的深刻理解了,现在要进阶了,做更加难的事情了,这是分布式集群的重大特征,在业务量爆炸式增长的场景中,就需要提前考虑根据业务进行分片,在分片的学习中,也得到了victer大神和山狼的的指点,遗憾的是后来山狼因为工作忙碌,交流的越来越少了,而victor大神一直经常交流中,对于分片的尝试,整理在下面:

 

Mycat高可用分片er分片的2种场景:http://blog.csdn.net/mchdba/article/details/50655304                                                                                                                                               

Mycat连续分片-自定义数字分片:http://blog.csdn.net/mchdba/article/details/50656337

Mycat连续分片-按日期分片:http://blog.csdn.net/mchdba/article/details/50656478

Mycat离散分片-枚举:http://blog.csdn.net/mchdba/article/details/50656478

Mycat离散分片-程序指定的分区分片:http://blog.csdn.net/mchdba/article/details/50656500

 

 

在分片的场景中,还有一种业务类型,就是一个分片故障了,如何迁移到新的分片,这个思路实现如下:

 

Mycat分片中快速迁移思路:http://blog.csdn.net/mchdba/article/details/50939614                                                                                                                                                            

Mycat分片中平滑迁移实施过程:http://blog.csdn.net/mchdba/article/details/50991649

 

 

6,瑕不掩瑜,mycat的斑点

Mycat有诸多优点,但是也有它不足的地方,比如分页、跨事务、存储过程、对db2、mongodb的支持等等,这些都需要了解熟悉,以免在使用的时候给别人挖坑,对这些方面,我们需要了解到实现的细节,然后再用案例去验证,分析问题症结所在,如果有java代码coding能力,甚至可以修改完善这些不足,对此有整理如下:

 

Mycat分页慢解惑、跨事务解析、注解调用存储过程:http://blog.csdn.net/mchdba/article/details/50719120                                                                                                             

 

 

 

7,健壮持久,多多益善

在互联网分布式应用中,最重要的就是高可用了,高可用能保证应用的持续可用性,这样能7*24,而mycat也有类似的集群架构,这是了解mycat深入mycat必须的历程:

 

Mycat集群实现:http://blog.csdn.net/mchdba/article/details/50867885                                                                                                                                                                 

 

 

为了mycat应用部署的健壮持续,我们需要多mycat进行全方位的监控,有了这些监控数据,我们可以了解到mycat运行的信息,对于优化mycat非常有用,关于这个我有整理如下:

 

Mycat性能采集:http://blog.csdn.net/mchdba/article/details/50727099                                                                                                                                                                   

 

 

了解到这里,我们就知道,在部署分布式集群架构之前,肯定需要进行各种压力测试,来了解mycat的阀值以及它能达到的性能极限,能支撑多少高并发、tps、qps等等,那么这里就有一个自带的工具可以达到我们的效果:

 

监控mycat压力测试的性能曲线:http://blog.csdn.net/mchdba/article/details/51050008                                                                                                                                      

 

 

PS:其实走到这里,行程都是蛮轻松的,不太劳累,有点小小得意了,只是常言道人无远虑必有近忧,接下来就碰到问题了。

 


8,衣带渐宽终不悔,为伊消得人憔悴

第一道坎,连接不上oracle数据源:

在加载oracle数据源的时候,需要把oracle的jar包放到mycat安装目录下,一般是用这个ojdbc14.jar,放到/usr/mysql/mycat/lib目录下面,然后重新加载下mycat生效。

 

第二道坎,中文乱码:

在熟悉这个里面,我遇到坎了,是最富盛名的中文乱码问题,oracle里面字符集是gbk,mysql里面是utf8,而mycat也是utf8,对于这种差异,如何操作,我搜索了很久,没有找到合适的方案,忙到半夜11点时候,咨询leader的时候,遇到了leader的一句神回复“设置成utg”,然后我设置在了mycat的配置文件server.xml里面:

[root@oracle_standby ~]# vim /usr/local/mycat/conf/server.xml                                                                                                                                                                                

<!DOCTYPE mycat:server SYSTEM "server.dtd">

<mycat:server xmlns:mycat="http://org.opencloudb/">

        <system>

        <property name="charset">utg</property>

……

结果我继续调试了,发现还是乱码,然后觉得leader指点的应该没有错,可能是别的问题导致的,继续调试重组mycat各种情况调试,1个半小时过去后,还是乱码,然后引发了牛人静哥出来了,她说是字符集设置问题,而且我的设置utg是不对的。然后我顿然醒悟,终于意识到leader的神回复utg是错误的,经验总结不能100%相信权威啊,因为万一不小心会被他带进坑里,结果我不得已回头重新整理思路,而那时已经1:00了,窗外夜沉如水,我去冲了个凉水澡,回来继续研究。

 

泠静下来后,整理思路,再奋战了1个小时后,搞定了,思路整理如下:

Mycat对于数据库而言就是客户端,一般来讲客户端字符编码与数据库服务端一致就不会有什么问题,或者是严格超集,保证插入到数据库不因转码而丢失。客户端、系统终端、数据库三者字符庥得协调,否则不一致的话,会有字符集转换的问题,有时候,显示正确的,但不一定在数据库就保存正确,或者保存到数据库的数据编码正确,没准显示为乱码。这就意味着,在oracle里面是gbk或者latin1啥都没有关系,只要做好以下3点:

(1),在迁移到mysql里面,在mycat平台上从oracle导出时候字符集设置为utf8

(2),在mycat平台上导入到mysql字符集也要设置为utf8

(3), 然后在mycat平台上查看数据也要设置字符集为utf8

做好了以上3点,三而合一,这样就能正常显示中文了。

 

Mycat平台上实现oracle迁移到mysql:http://blog.csdn.net/mchdba/article/details/50995059                                                                                                                                        

 

 

第二天闹钟换我起床,睡眼朦胧,镜中熊猫眼,^_^

 

 

9,奇女子静哥

看到她的名字“静哥”,我不由得自主想起了一首流传甚久的歌曲“我不是黄蓉我不懂武功我只要静哥哥完美的爱情……”,这首歌曲是不是很平民化很雨很有喜感啊,反正我觉得蛮接地气的哈,歌曲地址是:http://bd.kuwo.cn/yinyue/90334?from=baidu,因为作为金庸迷,对这个太敏感了,所以对她印象很深刻,而且她mycat技术很好口才也好,活脱脱一个现代版小黄蓉啊,而且据leader发的照片来看,确实是标准的江南美女,而且难得的是她刚工作不久还是单身。

 

SO说道在这里,大家都懂了吧,有想认识她学习mycat技术或者准备拓展mycat业务的,在文后评论区留下你的email地址并标注静哥,我会给你发email的告诉联系方式的。

 

 

10,瑞士军刀、亲亲山庄、中国开源第一门派

到此位置,mycat的重要功能点基本完成了,然后就是师傅临进门修行在个人了,哦对了,还有Mycat最后一个重要点,mycat-eye,这个是蛮有用的,not only formyat,当然目前还是一个半成品,梦想是成为mysql伴侣,只要用了mysql,就离不开mycat-eye,当然梦想是美好,现实是需要我们大家一起去实践去完善它,尽管如此,mycat-eye还是有它独特的闪光点:

 

Mycat瑞士军刀:http://blog.csdn.net/mchdba/article/details/51059547                                                                                                                                                                               

 

最后,介绍下,mycat的带路人,leader-us,看名字,就知道他是mycat的发起人,架构实力很深厚,口才也很好,目前给我感觉是技术领域中营销实力最强的、映像领域中技术实力最强的。他能看到mycat的市场并且开始运作成立mycat高端服务公司,是很有魄力的。

 

所以他有成为类似马云那样的企业家的潜质的,他的梦想是成立亲亲山庄,做高端技术服务和支持,成立咨询公司,并且做到中国的apache,成为国内开源界的No1,当然了个人实力有限,所以需要大家一起努力,目前开启众筹活动,起步是一人5W,大概预计征集70几个人,启动资金有300W到400W左右,他就可以全职参与并运营亲亲山庄了。

 

亲亲山庄的选址是广州到珠海之间的海岛上,风景宜人,适合居住生活。

 

11,尾声,左兄与任正非、leader-us与马云

新成立的公司里面,有个左兄,很传奇,大一在大学入伍,然后复员专业,来上海学IT,年纪轻轻,睡在地铁站,苦心专研数据库、系统、中间件,现在已经成为了业界大牛,上海地区mycat标杆人物,和他接触过,胆大心细脸皮厚,而且对朋友和身边人仗义,深深懂得利益均沾的道理并且也言行一致,觉得他有任年轻时候的影子,未来成就无限。

 

然后就是leader-us,他有马云的口才,还有王坚的技术功底,可以说能说服很多人,而且这次众筹选择的对象也很准确,选择的是在北上广深一线城市税后1.5W的从业人员和南京武汉重庆福州二线城市税后1W的从业人群,对市场目标定位准确,所以leader-us成功的概率非常大,这也是我和左兄还有很多朋友决定加入这个创业团队的主要原因吧。

 

目前众筹已经结束,资金已经到位,已经开始开展mycat高端技术支持服务,大家有需要的,可以在下面评论区留下email地址,我会第一时间联系回复你的,谢谢。



为什么要有Mycat---Mycat的前世今生

原创 2017年03月15日 20:49:50
  • 4361

序言

如果我有一个32核心的服务器,我就可以实现1个亿的数据分片,我有32核心的服务器么?没有,所以我至今无法实现1个亿的数据分片。——Mycat’s Plan 
上面这句话是Mycat 1.0快要完成时候的一段感言,而当发展到Mycat 1.3的时候,我们又有了一个新的Plan: 
如果我们有10台物理机,我们就可以实现1000亿的数据分片,我们有10台物理机么?没有,所以,Mycat至今没有机会验证1000亿大数据的支撑能力——Mycat’s Plan 2.0 
“每一个成功的男人背后都有一个女人”。自然Mycat也逃脱不了这个法则。Mycat背后是阿里曾经开源的知名产品——Cobar。Cobar的核心功能和优势是MySQL数据库分片,此产品曾经广为流传,据说最早的发起者对Mysql很精通,后来从阿里跳槽了,阿里随后开源的Cobar,并维持到2013年年初,然后,就没有然后了。 
Cobar的思路和实现路径的确不错。基于Java开发的,实现了MySQL公开的二进制传输协议,巧妙地将自己伪装成一个MySQL Server,目前市面上绝大多数MySQL客户端工具和应用都能兼容。比自己实现一个新的数据库协议要明智的多,因为生态环境在哪里摆着。 
Cobar使用起来也非常方便。由于是基于Java语言开发的,下载下来解压,安装JDK,然后配置几个不是很复杂的配置文件,猛击鼠标,就能启动Cobar。因此这个开源产品赢得了很多Java粉丝以及PHP用户的追捧。当然,笨人(Leader us)也跟着进入,并且在某个大型云项目中——“苦海无边”的煎着熬,良久。 
爱情就像是见鬼。只有撞见了,你才会明白爱情是怎么回事。TA是如此神秘,欲语还羞。情窦初开的你又玩命将TA的优点放大,使自己成为一只迷途的羔羊。每个用过Cobar的人就像谈过一段一波三折、荡气回肠的爱情,令你肝肠寸断。就像围城:里面的人已经出不来了,还有更多的人拼命想挤进去。 
仅以此文,献给哪些努力在IT界寻求未来的精英和小白们,还有更多被无视的,正准备转行的同仁,同在江湖混,不容易啊,面试时候就装装糊涂,放人家一马,说不定,以后又是一个Made in China的乔布斯啊。

曾经的她

曾经的她,长发飘飘,肤若凝脂,国色天香,长袖善舞,所以,一笑倾城。 
那已成传说,一如您年少时的坚持:“书中自有黄金屋…” 
Cobar曾是多少IT骚年心中的那个TA,有关Cobar的这段美好的描述(不能说是广告)俘虏了众多程序猿躁动纯真的心: 
Cobar是阿里巴巴研发的关系型数据的分布式处理系统,该产品成功替代了原先基于Oracle的数据存储方案,目前已经接管了3000+个MySQL数据库的schema,平均每天处理近50亿次的SQL执行请求。 
50亿有多大?99%的普通人类看到这个数字,已经不能呼吸。当然,我指的是RMB。99%的程序猿除了对工资比较敏感,其实对数字通常并不感冒。上面这个简单的数字描述,已立刻让我们程序型的大脑短路。恨不得立刻百度Cobar,立刻Download,立刻熬夜研究。做个简单的推算,50亿次请求转换为每个schema每秒的数据访问请求即TPS,于是我们得到一个让自己不能相信的数字:20TPS,每秒不到20个访问。 
Cobar最重要的特性是分库分表。Cobar可以让你把一个MySQL的Table放到10个甚至100个位于不同物理机上的MySQL服务器上去存储,而在用户看来是一张表(逻辑表)。这样功能很有价值。比如:我们有1亿的订单,则可以划分为10个分片,存储到2-10个物理机上。每个MySQL服务器的压力减少,而系统的响应时间则不会增加。看上去很完美的功能,而且潜意识里,执行这句SQL:

select count(*) from order
  • 1

100%的人都会认为:会返回1条数据,但事实上,Cobar会返回N条数据,N=分片个数。 
接下来我们继续执行SQL:

 select count(*) from order order by order_date
  • 1

你会发现奇怪的乱序现象,而且结果还随机,这是因为,Cobar只是简单的把上述SQL发给了后端N个分片对应的MySQL服务器去执行,然后把结果集直接输出…. 
再继续看看,我们常用的Limit分页的结果…可以么?答案是:不可以。 
这个问题可以在客户端程序里做些工作来解决。所以随后出现了Cobar Client。据我所知,很多Cobar的使用者也都是自行开发了类似Cobar Client的工具来解决此类问题。从实际应用效果来说,一方面,客户端编程方式解决,困难度很高,Bug率也居高不下;另一方面,对于DBA和运维来说,增加了困难度。 
当你发现这个问题的严重性,再回头看看Cobar的官方文档,你怅然若失,四顾茫然。 
接下来,本文将隐藏在Cobar代码中那些不为人知的秘密逐一披漏,你洞悉了这些秘密,就会明白Mycat为什么会横空出世。

Cobar的十一个秘密

1 第一个秘密:Cobra会假死? 
是的,很多人遇到这个问题。如何来验证这点呢?可以做个简单的小实验,假如你的分片表中配置有表company,则打开mysql终端,执行下面的SQL:

select sleep(500) from company;
  • 1

此SQL会执行等待500秒,你再努力以最快的速度打开N个mysql终端,都执行相同的SQL,确保N>当前Cobra的执行线程数:

show @@threadpool
  • 1

的所有Processor1-E的线程池的线程数量总和,然后你再执行任何简单的SQL,或者试图新建立连接,都会无法响应,此时

show @@threadpool
  • 1

里面看到TASK_QUEUE_SIZE已经在积压中。 
不可能吧,据说Cobra是NIO的非阻塞的,怎么可能阻塞!别激动,去看看代码,Cobra前端是NIO的,而后端跟Mysql的交互,是阻塞模式,其NIO代码只给出了框架,还未来得及实现。真相永远在代码里,所以,为了发现真相,还是转行去做码农吧!貌似码农也像之前的技术工人,越来越稀罕了。 
2 第二个秘密:高可用的陷阱? 
每一个秘密的背后,总是隐藏着更大的秘密。Cobra假死的的秘密背后,还隐藏着一个更为“强大”的秘密,那就是假死以后,Cobra的频繁主从切换问题。我们看看Cobra的一个很好的优点——“高可用性”的实现机制,下图解释了Cobra如何实现高可用性: 
分片节点dn2_M1配置了两个dataSource,并且配置了心跳检测(heartbeat)语句,在这种配置下,每个dataNode会定期对当前正在使用的dataSource执行心跳检测,默认是第一个,频率是10秒钟一次,当心跳检测失败以后,会自动切换到第二个dataSource上进行读写,假如Cobra发生了假死,则在假死的1分钟内,Cobra会自动切换到第二个节点上,因为假死的缘故,第二个节点的心跳检测也超时。于是,1分钟内Cobra频繁来回切换,懂得MySQL主从复制机制的人都知道,在两个节点上都执行写操作意味着什么?——可能数据一致性被破坏,谁也不知道那个机器上的数据是最新的。 
还有什么情况下,会导致心跳检测失败呢?这是一个不得不说的秘密:当后端数据库达到最大连接后,会对新建连接全部拒绝,此时,Cobar的心跳检测所建立的新连接也会被拒绝,于是,心跳检测失败,于是,一切都悄悄的发生了。 
幸好,大多数同学都没有配置高可用性,或者还不了解此特性,因此,这个秘密,一直在安全的沉睡。 
3 第三个秘密:看上去很美的自动切换 
Cobar很诱人的一个特性是高可用性,高可用性的原理是数据节点DataNode配置引用两个DataSource,并做心跳检测,当第一个DataSource心跳检测失败后,Cobar自动切换到第二个节点,当第二个节点失败以后,又自动切换回第一个节点,一切看起来很美,无人值守,几乎没有宕机时间。 
在真实的生产环境中,我们通常会用至少两个Cobar实例组成负载均衡,前端用硬件或者HAProxy这样的负载均衡组件,防止单点故障,这样一来,即使某个Cobar实例死了,还有另外一台接手,某个Mysql节点死了,切换到备节点继续,至此,一切看起来依然很美,喝着咖啡,听着音乐,领导视察,你微笑着点头——No problem,Everything is OK!直到有一天,某个Cobar实例果然如你所愿的死了,不管是假死还是真死,你按照早已做好的应急方案,优雅的做了一个不是很艰难的决定——重启那个故障节点,然后继续喝着咖啡,听着音乐,轻松写好故障处理报告发给领导,然后又度过了美好的一天。 
你忽然被深夜一个电话给惊醒,你来不及发火,因为你的直觉告诉你,这个问题很严重,大量的订单数据发生错误很可能是昨天重启cobar导致的数据库发生奇怪的问题。你努力排查了几个小时,终于发现,主备两个库都在同时写数据,主备同步失败,你根本不知道那个库是最新数据,紧急情况下,你做了一个很英明的决定,停止昨天故障的那个cobar实例,然后你花了3个通宵,解决了数据问题。 
这个陷阱的代价太高,不知道有多少同学中枪过,反正我也是躺着中枪过了。若你还不清楚为何会产生这个陷阱,现在我来告诉你:

  • Cobar启动的时候,会用默认第一个Datasource进行数据读写操作;
  • 当第一个Datasource心跳检测失败,会切换到第二个Datasource;
  • 若有两个以上的Cobar实例做集群,当发生节点切换以后,你若重启其中任何一台Cobar,就完美调入陷阱;

那么,怎么避免这个陷阱?目前只有一个办法,节点切换以后,尽快找个合适的时间,全部集群都同时重启,避免隐患。为何是重启而不是用节点切换的命令去切换?想象一下32个分片的数据库,要多少次切换? 
MyCAT怎么解决这个问题的?很简单,节点切换以后,记录一个properties文件( conf目录下),重启的时候,读取里面的节点index,真正实现了无故障无隐患的高可用性。

4 第四个秘密:只实现了一半的NIO 
NIO技术用作JAVA服务器编程的技术标准,已经是不容置疑的业界常规做法,若一个Java程序员,没听说过NIO,都不好意思说自己是Java人。所以Cobar采用NIO技术并不意外,但意外的是,只用了一半。 
Cobar本质上是一个“数据库路由器”,客户端连接到Cobar,发生SQL语句,Cobar再将SQL语句通过后端与MySQL的通讯接口Socket发出去,然后将结果返回给客户端的Socket中。下面给出了SQL执行过程简要逻辑:

SQL->FrontConnection->Cobar->MySQLChanel->MySQL
FrontConnection 
  • 1
  • 2

实现了NIO通讯,但MySQLChanel则是同步的IO通讯,原因很简单,指令比较复杂,NIO实现有难度,容易有BUG。后来最新版本Cobar尝试了将后端也NIO化,大概实现了80%的样子,但没有完成,也存在缺陷。 
由于前端NIO,后端BIO,于是另一个有趣的设计产生了——两个线程池,前端NIO部分一个线程池,后端BIO部分一个线程池。各自相互不干扰,但这个设计的结果,导致了线程的浪费,也对性能调优带来很大的困难。 
由于后端是BIO,所以,也是Cobar吞吐量无法太高、另外也是其假死的根源。 
MyCAT在Cobar的基础上,完成了彻底的NIO通讯,并且合并了两个线程池,这是很大一个提升。从1.1版本开始,MyCAT则彻底用了JDK7的AIO,有一个重要提升。 
5 第五个秘密:阻塞、又见阻塞 
Cobar本质上类似一个交换机,将后端Mysql 的返回结果数据经过加工后再写入前端连接并返回,于是前后端连接都存在一个“写队列”用作缓冲,后端返回的数据发到前端连接FrontConnection的写队列中排队等待被发送,而通常情况下,后端写入的的速度要大于前端消费的速度,在跨分片查询的情况下,这个现象更为明显,于是写线程就在这里又一次被阻塞。 
解决办法有两个,增大每个前端连接的“写队列”长度,减少阻塞出现的情况,但此办法只是将问题抛给了使用者,要是使用者能够知道这个写队列的默认值小了,然后根据情况进行手动尝试调整也行,但Cobar的代码中并没有把这个问题暴露出来,比如写一个告警日志,队列满了,建议增大队列数。于是绝大多数情况下,大家就默默的排队阻塞,无人知晓。 
MyCAT解决此问题的方式则更加人性化,首先将原先数组模式的固定长度的队列改为链表模式,无限制,并且并发性更好,此外,为了让用户知道是否队列过长了(一般是因为SQL结果集返回太多,比如1万条记录),当超过指定阀值(可配)后,会产生一个告警日志。

<system><property name="frontWriteQueueSize">1024</property></system>
  • 1

6 第六个秘密:又爱又恨的SQL 批处理模式 
正如一枚硬币的正反面无法分离,一块磁石怎样切割都有南北极,爱情中也一样,爱与恨总是纠缠着,无法理顺,而Cobar的 SQL 批处理模式,也恰好是这样一个令人又爱又恨的个性。 
通常的SQL 批处理,是将一批SQL作为一个处理单元,一次性提交给数据库,数据库顺序处理完以后,再返回处理结果,这个特性对于数据批量插入来说,性能提升很大,因此也被普遍应用。JDBC的代码通常如下:

String sql = "insert into travelrecord (id,user_id,traveldate,fee,days) values(?,?,?,?,?)"; 
ps = con.prepareStatement(sql); 
for (Map<String, String> map : list) { 
ps.setLong(1, Long.parseLong(map.get("id")));
 ps.setString(2, (String) map.get("user_id")); 
ps.setString(3, (String) map.get("traveldate"));
 ps.setString(4, (String) map.get("fee")); 
ps.setString(5, (String) map.get("days")); 
ps.addBatch(); 
}
ps.executeBatch();
con.commit(); 
ps.clearBatch();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

但Cobar的批处理模式的实现,则有几个地方是与传统不同的:

  • 提交到cobar的批处理中的每一条SQL都是单独的数据库连接来执行的
  • 批处理中的SQL并发执行

并发多连接同时执行,则意味着Batch执行速度的提升,这是让人惊喜的一个特性,但单独的数据库连接并发执行,则又带来一个意外的副作用,即事务跨连接了,若一部分事务提交成功,而另一部分失败,则导致脏数据问题。看到这里,你是该“爱”呢还是该“恨”? 
先不用急着下结论,我们继续看看Cobar的逻辑,SQL并发执行,其实也是依次获取独立连接并执行,因此还是有稍微的时间差,若某一条失败了,则cobar会在会话中标记”事务失败,需要回滚“,下一个没执行的SQL就抛出异常并跳过执行,客户端就捕获到异常,并执行rollback,回滚事务。绝大多数情况下,数据库正常运行,此刻没有宕机,因此事务还是完整保证了,但万一恰好在某个SQL commit指令的时候宕机,于是杯具了,部分事务没有完成,数据没写入。但这个概率有多大呢?一条insert insert 语句执行commit指令的时间假如是50毫秒,100条同时提交,最长跨越时间是5000毫秒,即5秒中,而这个C指令的时间占据程序整个插入逻辑的时间的最多20%,假如程序批量插入的执行时间占整个时间的20%(已经很大比例了),那就是20%×20%=4%的概率,假如机器的可靠性是99.9%,则遇到失败的概率是0.1%×4%=十万分之四。十万分之四,意味着99.996%的可靠性,亲,可以放心了么? 
另外一个问题,即批量执行的SQL,通常都是insert的,插入成功就OK,失败的怎么办?通常会记录日志,重新找机会再插入,因此建议主键是能日志记录的,用于判断数据是否已经插入。 
最后,假如真要多个SQL使用同一个后端MYSQL连接并保持事务怎么办?就采用通常的事务模式,单条执行SQL,这个过程中,Cobar会采用Session中上次用过的物理连接执行下一个SQL语句,因此,整个过程是与通常的事务模式完全一致。 
7 第七个秘密:庭院深深锁清秋 
说起死锁,貌似我们大家都只停留在很久远的回忆中,只在教科书里看到过,也看到过关于死锁产生的原因以及破解方法,只有DBA可能会偶尔碰到数据库死锁的问题。但很多用了Cobar的同学后来经常发现一个奇怪的问题,SQL很久没有应答,百思不得其解,无奈之下找DBA排查后发现竟然有数据库死锁现象,而且比较频繁发生。要搞明白为什么Cobar增加了数据库死锁的概率,只能从源码分析,当一个SQL需要拆分为多条SQL去到多个分片上执行的时候,这个执行过程是并发执行的,即N个SQL同时在N个分片上执行,这个过程抽象为教科书里的事务模型,就变成一个线程需要锁定N个资源并执行操作以后,才结束事务。当这N个资源的锁定顺序是随机的情况下,那么就很容易产生死锁现象,而恰好Cobar并没有保证N个资源的锁定顺序,于是我们再次荣幸“中奖”。 
8 第八个秘密:出乎意料的连接池 
数据库连接池,可能是仅次于线程池的我们所最依赖的“资源池”,其重要性不言而喻,业界也因此而诞生了多个知名的开源数据库连接池。我们知道,对于一个MySQL Server来说,最大连接通常是1000-3000之间,这些连接对于通常的应用足够了,通常每个应用一个Database独占连接,因此足够用了,而到了Cobar的分表 
分库这里,就出现了问题,因为Cobar对后端MySQL的连接池管理是基于分片——Database来实现的,而不是整个MySQL的连接池共享,以一个分片数为100的表为例,假如50个分片在Server1上,就意味着Server1上的数据库连接被切分为50个连接池,每个池是20个左右的连接,这些连接池并不能互通,于是,在分片表的情况下,我们的并发能力被严重削弱。明明其他水池的水都是满的,你却只能守着空池子等待。。。 
9 第九个秘密:无奈的热装载 
Cobar有一个优点,配置文件热装载,不用重启系统而热装载配置文件,但这里存在几个问题,其中一个问题是很多人不满的,即每次重载都把后端数据库重新断连一次,导致业务中断,而很多时候,大家改配置仅仅是为了修改分片表的定义,规则,增加分片表或者分片定义,而不会改变数据库的配置信息,这个问题由来已久,但却不太好修复。 
10 第十个秘密:不支持读写分离 
不支持读写分离,可能熟悉相关中间件的同学第一反应就是惊讶,因为一个MySQL Proxy最基本的功能就是提供读写分离能力,以提升系统的查询吞吐量和查询性能。但的确Cobar不支持读写分离,而且根据Cobar的配置文件,要实现读写分离,还很麻烦。可能有些人认为,因为无法保证读写分离的时延,因此无法确定是否能查到之前写入的数据,因此读写分离并不重要,但实际上,Mycat的用户里,几乎没有不使用读写分离功能的,后来还有志愿者增加了强制查询语句走主库(写库)的功能,以解决刚才那个问题。 
11 第十一个秘密:不可控的主从切换 
Cobar提供了MySQL主从切换能力,这个功能很实用也很方便,但你无法控制它的切换开启或关闭,有时候我们不想它自动切换,因为到目前为止,还没有什么好的方法来确认MySQL写节点宕机的时候,备节点是否已经100%完成数据同步,因此存在数据不一致的风险,如何更可靠的确定是否能安全切换,这个问题比较复杂,Mycat也一直在努力完善这个特性。

Mycat闪耀登场

当大批软件工程师开始觉醒,用互联网思维思考和规划自己的人生,第四次工业革命才拉开序幕——《Mycat宣言》 
Mycat最早的版本完成于2013年年底,实现于雾霾中的北京城。 
Mycat要解决的第一个问题就是要将Cobar后端实现为非阻塞模式。将Cobar从“个人版”提升到真正的“企业版”。据未经证实的渠道了解,非开源的Cobar内部版本已经实现后端NIO,但是并没有开源出来。于是Mycat注定要诞生了,尽管可能不会是Leader-us发起的。 
但软件界里,总会有那么一些桀骜不驯的人,用一个电脑,在某一个不经意的晚上,写了一段代码,惊艳了这个世界。 
Mycat的前身是OpencloudDB,而现在的Mycat QQ群则用来开发一个叫做MycloudOA的云平台的SAAS企业办公软件的,半年的时间里,这个群聚集了一大帮IT人,拥有超过10个“顾问”头衔的、超过十个“架构师”头衔的、超过20个“研发”头衔的庞大志愿者团队,然后,仅有不到3个人提交过文档和少量代码,其他的人都很专业的谈论着需求、谈论着框架、谈论着市场,最后的最后,大家都变成了资深酱油瓶,于是MycloudOA出师未捷身先死。 
OpencloudDB改名为Mycat,一个原因是简单好记,另外一个原因,是打算未来入驻Apache。因为Apache Tomcat也是一只猫,从年龄来看,Tomcat算是Mycat表姐吧,从相貌身材来看,Tomcat她表妹,绝对是东方第一萌妹子,虽然目前Rainbow大侠设计的Mycat Logo,看起来是个100%的女汉子。 
Mycat 1.0的发布,立即引起不少人的关注,曾经参与MycloudOA开发的一些小伙伴陆续加入进来,资深酱油师Michael还注册了一个openclouddb的网站,随后又实现了Mycat全局序列号(基于文件方式);一些了解或使用过Cobar的同学也陆续加入,网名为无影的大侠,提供了最早的Mycat分页排序的源码,最早在生产系统上部署了Mycat并且采用HA Proxy方式做高可用方案;随后,一个叫做小鱼的PHP高手,在不到3个月时间内,用Mycat改造了原先的电商系统。后来又有一些美容美发的SAAS创业项目采用了Mycat;再后来,一些比较大的电信软件领域的公司和项目开始使用Mycat,他们中的大多数都对Mycat做过不少的贡献,比如测试,Bug修复等。发展到今天,Mycat核心研发团队里的大多数人,都是来自上述这些公司。 
Mycat1.3的诞生,是Mycat历史上最重大的一个里程碑。在这个版本里,需求、测试和功能开发各项工作,首次从个人为主变为开源团队为主的模式,更多的人参与到需求、开发、测试以及Bug修复活动中,基本上确定的Bug都在24小时内修复并有志愿者或用户确认修复。Mycat 1.3版本的性能与1.2比提升巨大,功能更完备,这是因为包括武、成都-研发、冰峰影、Leader-us等实力派编程高手各自负责一部分重要模块并一起协同研发,后来又加入聆听、从零开始、南哥、Mclaren、兵临城下等新的一批实力派编程达人,以及正在排队等待收编的PCY实力派干将,其他关于参与Mycat官网建设、文档编写和翻译的就更多了(当然也失联很多)。截至目前,Mycat志愿者团队有以Marshy大美女为首的负责官网和广告的团队,以Leader-us为首的负责Mycat-Server研发的团队、以Rainbow为首的Mycat-Web的研发团队、以海王星为首的QA团队,以及群龙无首的测试团队和DBA团队。 
此外,Mycat开源社区正在进一步强化数据库监控、智能调优等方面的功能,未来将实现一键优化的能力,根据拦截到的SQL的执行统计数据,自动分析热点数据、给出建议的索引和优化措施以及读写分离的建议,DBA一键完成优化,数据迁移也将可以在节目上点击鼠标完成。 
Mycat截至到2015年4月,保守估计已经有超过60个项目在使用,主要应用在电信领域、互联网项目,大部分是交易和管理系统,少量是信息系统。比较大的系统中,数据规模单表单月30亿。以后Mycat和Mycat社区成为IT和互联网创业的最佳伴侣。

Mycat概述

1 功能介绍 
Mycat是什么?从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的的Server,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生(Native)协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。 Mycat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在Mycat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度,在测试阶段,可以将一个表定义为任何一种Mycat支持的存储方式,比如MySQL的MyASIM表、内存表、或者MongoDB、LevelDB以及号称是世界上最快的内存数据库MemSQL上。试想一下,用户表存放在MemSQL 
上,大量读频率远超过写频率的数据如订单的快照数据存放于InnoDB中,一些日志数据存放于MongoDB中,而且还能把Oracle的表跟MySQL的表做关联查询,你是否有一种不能呼吸的感觉?而未来,还能通过Mycat自动将一些计算分析后的数据灌入到Hadoop中,并能用Mycat+Storm/Spark Stream引擎做大规模数据分析,看到这里,你大概明白了,Mycat是什么?Mycat就是BigSQL,Big Data On SQL Database。 
对于DBA来说,可以这么理解Mycat: Mycat就是MySQL Server,而Mycat后面连接的MySQL Server,就好象是MySQL的存储引擎,如InnoDB,MyISAM等,因此,Mycat本身并不存储数据,数据是在后端的MySQL上存储的,因此数据可靠性以及事务等都是MySQL保证的,简单的说,Mycat就是MySQL最佳伴侣,它在一定程度上让MySQL拥有了能跟Oracle PK的能力。 
对于软件工程师来说,可以这么理解Mycat: 
Mycat就是一个近似等于MySQL的数据库服务器,你可以用连接MySQL的方式去连接Mycat(除了端口不同,默认的Mycat端口是8066而非MySQL的3306,因此需要在连接字符串上增加端口信息),大多数情况下,可以用你熟悉的对象映射框架使用Mycat,但建议对于分片表,尽量使用基础的SQL语句,因为这样能达到最佳性能,特别是几千万甚至几百亿条记录的情况下。 
对于架构师来说,可以这么理解Mycat: 
Mycat是一个强大的数据库中间件,不仅仅可以用作读写分离、以及分表分库、容灾备份,而且可以用于多租户应用开发、云平台基础设施、让你的架构具备很强的适应性和灵活性,借助于即将发布的Mycat智能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表映射到不同存储引擎上,而整个应用的代码一行也不用改变。 
当前是个大数据的时代,但究竟怎样规模的数据适合数据库系统呢?对此,国外有一个数据库领域的权威人士说了一个结论:千亿以下的数据规模仍然是数据库领域的专长,而Hadoop等这种系统,更适合的是千亿以上的规模。所以,Mycat适合1000亿条以下的单表规模,如果你的数据超过了这个规模,请投靠Mycat Plus吧! 
2 Mycat原理 
Mycat的原理并不复杂,复杂的是代码,如果代码也不复杂,那么早就成为一个传说了。 
Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。 
这里写图片描述
上述图片里,Orders表被分为三个分片datanode(简称dn),这三个分片是分布在两台MySQL Server上(DataHost),即datanode=database@datahost方式,因此你可以用一台到N台服务器来分片,分片规则为(sharding rule)典型的字符串枚举分片规则,一个规则的定义是分片字段(sharding column)+分片函数(rule function),这里的分片字段为prov而分片函数为字符串枚举方式。 
当Mycat收到一个SQL时,会先解析这个SQL,查找涉及到的表,然后看此表的定义,如果有分片规则,则获取到SQL里分片字段的值,并匹配分片函数,得到该SQL对应的分片列表,然后将SQL发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端。以select * from Orders where prov=?语句为例,查到prov=wuhan,按照分片函数,wuhan返回dn1,于是SQL就发给了MySQL1,去取DB1上的查询结果,并返回给用户。 
如果上述SQL改为select * from Orders where prov in (‘wuhan’,‘beijing’),那么,SQL就会发给MySQL1与MySQL2去执行,然后结果集合并后输出给用户。但通常业务中我们的SQL会有Order By 以及Limit翻页语法,此时就涉及到结果集在Mycat端的二次处理,这部分的代码也比较复杂,而最复杂的则属两个表的Jion问题,为此,Mycat提出了创新性的ER分片、全局表、HBT(Human Brain Tech)人工智能的Catlet、以及结合Storm/Spark引擎等十八般武艺的解决办法,从而成为目前业界最强大的方案,这就是开源的力量! 
3 应用场景 
Mycat发展到现在,适用的场景已经很丰富,而且不断有新用户给出新的创新性的方案,以下是几个典型的应用场景:

  • 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换
  • 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片
  • 多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化
  • 报表系统,借助于Mycat的分表能力,处理大规模报表的统计
  • 替代Hbase,分析大数据
  • 作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择

4 Mycat长期路线图

  • 强化分布式数据库中间件的方面的功能,使之具备丰富的插件、强大的数据库智能优化功能、全面的系统监控能力、以及方便的数据运维工具,实现在线数据扩容、迁移等高级功能。

  • 进一步挺进大数据计算领域,深度结合Spark Stream和Storm等分布式实时流引擎,能够完成快速的巨表关联、排序、分组聚合等 
    OLAP方向的能力,并集成一些热门常用的实时分析算法,让工程师以及DBA们更容易用Mycat实现一些高级数据分析处理功能。

  • 不断强化Mycat开源社区的技术水平,吸引更多的IT技术专家,使得Mycat社区成为中国的Apache,并将Mycat推到Apache基金会,成为国内顶尖开源项目,最终能够让一部分志愿者成为专职的Mycat开发者,荣耀跟实力一起提升。

  • 依托Mycat社区,聚集100个CXO级别的精英,众筹建设亲亲山庄,Mycat社区+亲亲山庄=中国最大IT O2O社区。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangshuang1631/article/details/62237346


Mycat 数据库分库分表中间件

国内最活跃的、性能最好的开源数据库中间件!

我们致力于开发高性能的开源中间件而努力!

实体书 Mycat权威指南 » 开源投票支持Mycat 下载 » start »

  MyCAT5

Mycat关键特性

关键特性

支持SQL92标准支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常见SQL语法遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理。基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群。支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster基于Nio实现,有效管理线程,解决高并发问题。支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页。支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join。支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。支持多租户方案。支持分布式事务(弱xa)。支持XA分布式事务(1.6.5)。支持全局序列号,解决分布式下的主键生成问题。分片规则丰富,插件化开发,易于扩展。强大的web,命令行监控。支持前端作为MySQL通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉。支持密码加密支持服务降级支持IP白名单支持SQL黑名单、sql注入攻击拦截支持prepare预编译指令(1.6)支持非堆内存(Direct Memory)聚合计算(1.6)支持PostgreSQL的native协议(1.6)支持mysql和oracle存储过程,out参数、多结果集返回(1.6)支持zookeeper协调主从切换、zk序列、配置zk化(1.6)支持库内分表(1.6)集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。

什么是MYCAT

一个彻底开源的,面向企业应用开发的大数据库集群支持事务、ACID、可以替代MySQL的加强版数据库一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品一个新颖的数据库中间件产品

MYCAT监控

支持对Mycat、Mysql性能监控支持对Mycat的JVM内存提供监控服务支持对线程的监控支持对操作系统的CPU、内存、磁盘、网络的监控

目标

低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。

1.5版本架构

MYCAT官方论坛地址已更新为:i.mycat.io 欢迎大家访问!MYCAT社区所打造的IT新生活!

长期规划2.0

完全实现分布式事务,完全的支持分布式。通过Mycat web(eye)完成可视化配置,及智能监控,自动运维。通过mysql 本地节点,完整的解决数据扩容难度,实现自动扩容机制,解决扩容难点。支持基于zookeeper的主从切换及Mycat集群化管理。通过Mycat Balance 替代第三方的Haproxy,LVS等第三方高可用,完整的兼容Mycat集群节点的动态上下线。接入Spark等第三方工具,解决数据分析及大数据聚合的业务场景。通过Mycat智能优化,分析分片热点,提供合理的分片建议,索引建议,及数据切分实时业务建议。

优势

基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。

MYCAT背后有一支强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证了MYCAT的产品质量。

MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。



Mycat从入门到放弃

原创 2016年11月15日 22:20:22
  • 57837

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

1.非分片字段查询

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时有非分片字段查询,请考虑放弃!

2.分页排序

先看一下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的处理逻辑如下图:

排序分页

在有排序呢条件的情况下,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时有分页排序,请考虑放弃!

3.任意表JOIN

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

单个DB中JOIN

JOIN操作的SQL如下

mysql>select p_name,t_name from player p, team t where p.no = 3 and p.team_id = t.id;

此时能查询出结果

p_namet_name
WadeHeat


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

分库JOIN

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

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

4.分布式事务

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

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

mysql>begin;

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

弱XA事务1

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

弱XA事务2

执行完成后Mycat等待前端发送 commit 或 rollback 命令。发送 commit 命令时,Mycat检测当前连接是否为 Prepare Ready 状态,若是,则将 commit 命令发送到各个DB节点。

弱XA事务3

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013235478/article/details/53178657




展开阅读全文

没有更多推荐了,返回首页