前言
由于今年一直在看mq,nosql相关的开源项目,所以在一开始要设计mysql集群的时候我总想将我的mysql打造成为可以横向扩展的大型集群,但在查阅相关资料之后我发现在mysql集群方面呈现百花齐放的场面,他不像mongodb,redis等有一个或少数几个经典的解决方案。mysql拥有类似主从复制,MGR,innodb-cluster,MMM等等等非常多的官方和非官方的集群方式,这在选择上就有了很大的困难,在经验缺乏的情况下很难从众多方式中选择到适合本系统的集群方案。这里我会把市面上所有的集群方案罗列出来做横向对比,最终找出最适合的方式。
集群方案对比
主从复制-mysql集群的基础
这是mysql最早的底层集群方案,基于主从复制来实现mysql的高可用,后面很多的方案都是在主从复制的基础上得出的。这里相信大家都熟悉这个方案,其原理就不多赘述了。我们主要来看一下它的优缺点。
优点
1.是mysql从单机到集群的里程碑,可以同时保持多个从节点做备份节点,实现数据备份。
2.可以开启从节点可读,让都请求分配到从节点做读写分离。
3.可以应用中指定读取是从主库读还是从库读,虽然不自动化,但是可以解决主从数据不一致问题。很多公司都是在用这种笨办法来处理需要强一致性的场景,让读写都是在主库执行,这样就不存在数据不一致了。
缺点
1.没有解决故障切换和自动路由,如果master挂掉,并且不容易在短时间内恢复时,我们要保证系统运行首先就是重新指定一个主库提供服务,在这种情况下我们要做的工作就比较多了。第一步需要我们重新配置mysql,指定主库后重启mysql。第二步要修改项目中mysql数据库的url。它做不动自动故障转移。
2.主从的复制引入了主节点和从节点之间的数据不一致问题,这让很多对数据一致性要求较高的场景下不能使用读写分离,单单是拿从库当备份。
总结:
对于中小型的项目还是很推荐这种方式的,可以手动指定一些东西来满足业务需要。也不需要引入复杂的分布式处理,系统比较简单易维护。
路由转发+主从-主从复制的进阶
上面我们讲的主从结构都有一个问题就是,没有故障自动转移和路由转发的功能,使用的时候非常麻烦。所以很多公司和个人就自己在mysql主从之上搭建了故障自动转移和路由转发的功能。这种模式的方案有很多,比如:keepalive+主从,haproxy+mysql,lvs+haproxy+mysql等等,这些方案都有一个特点,就是总能看到haproxy,lvs,keepalive的身影。其原理都一样就是对外提供一个唯一的入口ip,后端使用负载均衡和状态检测工具将请求转发到不同的mysql之上,在转发的过程中,如果出现宕机就自动转发到健康的节点上。
优点:
1.解决了故障自动转移和路由转发的问题,使用起来更加方便。
缺点:
1.版本太多,由于类似思想可以由很多种实现方式,所以方案杂乱无章。
2.由于是公司和个人为了解决路由转发问题所诞生的实现,并不是一个整套的集群解决方案,所以在分布式设计上不完善,比如脑裂问题等,并没有完善的解决。
总结:
这一块方案比较混杂,不好说哪种好哪种不好,只是都存在问题。我推荐如果是新项目在选择mysql集群方案时,如果不嫌麻烦可以使用主从方案,如果嫌麻烦可以使用上层mycat+底层主从复制代替这种方案。
主主复制-主从复制的改进
由于主从复制它的写节点只有一个,如果主节点挂掉没有另外的主节点可以代替,所以出现了主主复制。本质上就是一个mysql节点既是主节点,又是从节点,每个节点又能接收写请求,又能通过同步机制获取其他节点写入的数据。这样在主节点挂掉之后可以只要修改应用中的url,就可以让流量切换到备用主节点,不需要再去重新配置mysql。
优点:
1.主节点挂掉之后直接修改应用中mysql的url即可切换到备用主节点,省去重新配置mysql的步骤。
缺点:
1.没有解决故障切换和自动路由,这些工作还是要在应用中自己去解决。
2.本质上还是基于主从复制,数据一致性问题没有解决。
总结:
主主复制和主从复制我认为并没有很大程度上的创新,但确实是在故障情况下更方便些。在选型上我不倾向于这种,因为需要额外提供两台服务器做热备,而起到的作用并没有那么大。
路由转发+主主-主主复制的进阶
与主从一样,主主复制诞生之后,人们还是想进一步赋予它故障自动迁移和路由转发的能力,所以做了很多探索。主要方案还是与主从+路由转发一样。
优点:
1.解决了故障转换和路由转发的问题,使用起来更加方便。
缺点:
1.版本太多,由于类似思想可以由很多种实现方式,所以方案杂乱无章。
2.由于是公司和个人为了解决路由转发问题所诞生的实现,所以在分布式设计上不完善,比如脑裂问题等,并没有完善的解决。
总结:
还是那句话,建议用mycat+主从代替这种方案
MMM(Master-Master replication manager for MySQL)
由于上面混乱的场景出现了太久,所以催生了一个系统解决这方面问题的软件。它以主主复制为基础,是一套支持双主故障切换和双主日常管理的脚本程序,并且提供了统一的管理入口,一时间成为了非常经典的解决方案。
优点:
1.是一个整体化解决方案,包含了故障转移、自动读写分离、集群管理等功能。
缺点:
1.其核心没变,还是主主复制,所以主主复制所固有的数据一致性问题没有解决。
2.分布式问题还是没有很好的解决。
3.虽然是主主复制,但是mmm却不能支持多主并发写入。
总结:
要使用这个方案的话,其本身项目应该也有一定的规模了。对于有一定规模的项目我不推荐这种方案,因为它有了更好的代替解决方案,比如可以使用mycat+主从或者使用MHA或者innodb cluster。
MHA(Master High Availability)
这也是一个系统化的解决方案,听说还是比较成熟的。它有两种角色MHA Manager和MHA Node,MHA Manager单独部署,MHA Node与mysql节点部署在一台服务器上。它能通过一个MHA Manager来管理多个主从复制集群。如果集群中的master挂掉会自动找一个从节点提升为master。虽然底层还是主从复制,但是它结合半同步复制能在最大限度上保证数据的一致性。
优点:
1.已经开始有一个正规方案的样子了,其设计理念也比较完善了,其解决了master的重新选举。
2.通过与半同步复制配合,可以保证在故障切换的时候不丢数据,这是上面的方案所不具备的,上面的方案在故障切换时很大程度会丢数据。
3.根据网上搜集的资料,其已经是一个成熟的解决方案了。
缺点:
1.故障不能自动转移,需要引入其他vip组件。
2.数据一致性虽然比其他方案要好很多,但还是不能保障。基于半同步复制可以解决故障转移时不丢数据,但是由于其本质还是主从复制,所以数据一致性还是没有得到解决。
总结:
应该还是比较可靠的方式,但是苦于没有路由转发的功能,在应用层还要做一些封装。可以自行搞一套,也可以使用innodb-cluster。
mycat
这是我非常推荐的一款数据库中间件。它拥有故障自动转换,路由转发等集群底层功能,还拥有半自动分库分表等上层功能,相比较上面的几种解决方案,mycat有更多的成熟案例,它的功能也更加强大,完善。它不但解决了mysql集群方案问题,还解决了集群之后出现的跨库操作问题。
由于它中间件的特质,它可以与 其他集群方案结合使用,用来做集群上层的应用功能。比如与pxc集群相结合,与主从结合,使用mycat管理多个集群,做数据分片。
优点:
1.据我所知拥有很多成功案例。
2.功能强大。
缺点:
1.它本质上是一款数据库中间件,底层还是依赖mysql本身的集群,它只不过在其之上做了强大的功能。
2.不能支持mysql新的组复制和innodb cluster。
3.本质上还是基于主从复制,所以数据一致性问题解决的不好。但是可以手动选择不使用读写分离来解决主从同步过程中数据不一致导致的问题。
4.中间件的高可用又是一个问题。解决了mysql的高可用又要解决mycat的高可用。一套部署下来复杂度也挺高的。
总结:
对于大多数项目,我还是比较推荐这个方案的,因为它功能很完善,在数据一致性方面也可以解决。适合于大中型项目。
ndb cluster
它也是mysql官方推出的一款引擎级集群方案,本质上是一款分布式引擎。我认为它是mysql在集群方案上的探索之一,但缺是一个比较失败的探索,根据网上的资料,使用此方案的风评并不太好,我认为原因可能是它本身就是一款引擎,所以要使用它就要放弃最受欢迎的innodb引擎,大家可能更倾向于在innodb之上探索高可用高性能集群方案,而不是使用innodb来换取高可用高性能。
优点:
1.官方出品
2.了解的不多,不太清楚具体优点在哪
缺点:
1.与innodb不能兼容
总结:
不推荐这个方案,可以直接忽略了。
MGR(MySQL Group Replication)
在mysql5.7版本之后出现的新复制方式。以上集群方案全部都是基于主从复制以及主从复制的变种主主复制构建的,本质上对于数据一致性都解决的不好,但是在MGR出现之后,大大改善了这些问题。它虽然是一种复制方式,但是它的地位并不与主从,主主相同,它是一套更完备的数据同步解决方案,它的出现改变了曾经的底层集群架构。
其采用一致性协议paxos来构建复制过程,保证数据的最终一致性:
在事务写入的时候,也就是图中的Consensus过程,只有半数以上的节点同意,该消息才能写入集群。基于这个一致性协议,可以将整个集群扩展为拥有多个主节点的集群,只要主节点之间共同遵守paxos协议,那么就可以保证数据的一致性。
优点:
1.官方出品!(官方终于有动静了)。
2.基于组复制,mysql可以拥有横向扩展多主的能力了。它在实际使用时可以使用多主模式也可以使用单主模式。
3.一致性协议paxos一定程度上缓和了mysql数据一致性问题。
4.解决了故障的问题,即时有节点挂掉也不会影响整个系统。
缺点:
1.它仅仅是一个用于解决数据一致性问题和多主扩展的集群底层方案,并不能算是一套完整的集群解决方案,并没有路由转发等功能,相比较mycat这种完备的解决方案,差了很多。
总结:
这个方案没有做太多东西,只是提供了底层集群支持。还是要配合其他组件来使用。推荐直接跳过这个方案,直接使用基于组复制的innodb-cluster。
innodb-cluster
官方的又一力作,可能mysql也觉得自己在集群方案这一块太没有作为,所以一口气推出了很多方案。
innodb-cluster是基于组复制的一套完备集群方案,包括路由转发,故障切换,集群管理等。左等右等终于来了,innodb-cluster是真正意义上的mysql底层集群解决方案,拥有了集群管理的功能,对各方面功能也有很好的支持,主要是官方方案,稳定性,支持行应该会比较好。
优点:
1.官方出品。
2.是第一个完善的集群方案,如果说组复制只能称为是集群底层方案,那innodb cluster就是一个完善的集群方案了,其在组复制之上提供了路由转发,自动故障迁移,集群管理等一系列的功能。
3.基于组复制,它理论上可以实现横向扩展。
缺点:
1.因为基于组复制,所以数据也不是强一致性的。
2.只能支持innodb引擎。
总结:
目前还是比较推荐这套方案,因为他官方出品,基于最新的组复制,并且可以实现高可用集群,也可以实现高性能集群。是一整套集群解决方案。唯一的缺点是他没有mycat的各种上层功能,比如跨库join等。可以考虑底层使用innodb-cluster,上层接入mycat(不确定是否可行)。
pxc
一个另类出现了。他也是个mysql高可用的成熟解决方案。但它并没有使用mysql的底层集群支持,比如主从,组复制。它是完全通过上层软件将一个个单机mysql串联起来,这些单机mysql都是地位相同的主节点。正是由于这个原因,它可以保证数据在集群中的强一致性。如果你的项目需要强一致性的高可用方案,那选他绝对没错。
优点:
1.数据同步零延迟,且强一致性。
2.是一套成熟的高可用方案,解决了故障自动转移和路由转发,所有变动对用户透明。
缺点:
1.也是只能适用于innodb。
2.集群最少三台mysql机器。
3.集群受制于短板服务器的性能。
总结:
想要搭建数据强一致性集群,就是他了。
各种方案总结
对于小型项目的生产环境,还是推荐最简单的主从结构(也可以将主从替换为组复制,我认为这应该是mysql集群趋势)。
对于中型项目来说,mycat+主从是成功案例最多的方式。同时也比较推荐innodb-cluster,虽然案例不多,但是坑应该不多。
对于大型项目来说,innodb-cluster还太稚嫩,虽然好但是成功案例不多。还是推荐使用mycat+主从或者自建集群方案。
对于有些系统需要极高的数据一致性。那么推荐使用pxc。也可以使用一套pxc,一套其他方案。这样可以让强一致性的业务使用pxc,其他业务使用另一套方案。
我们的系统
一开始我想创建一个大的中心数据库,供整个系统使用。但是在思考过后这种方案并不好。
在前面的文章中,我把系统按照业务维度分成了:样本模块,血液模块,疫苗模块,健康管理模块,用户模块几个模块。由于这几个模块之间的耦合度很小,所以将大的中心数据库垂直拆分,每个模块使用自己独立的数据库是最好的方案。这样每个模块可以管理自己的数据库,互不影响,并且可以根据自己模块的实际情况选择合适的集群方案。
样本,血液模块分析:
1.这两个模块没有强一致性场景。
2.除了接收物流设备的信息,也没有其他高并发场景,而物流设备的存储是放在mongodb中的。
3.数据量不大,目前的样本信息在一百万上下,后期的增长不会太大,无需考虑分表。
所以在这两个模块中,我们使用mysql组复制架构做读写分离即可。
疫苗模块分析:
1.疫苗预约场景有比较大的并发量,而预约订单使用mysql存储。
2.疫苗是公司主要发力点,现拥有多个C端业务场景和众多潜在C端业务场景,后期可能会出现多个千万级亿级大表。
3.现存的疫苗预约业务和疫苗抢购秒杀业务为强一致性场景。
针对上述情况,我们采用两套数据库环境来解决。
1.mycat+组复制的架构搭建疫苗分片数据库。
2.mycat+pxc架构搭建强一致性集群。
其中把pxc集群单独拿出来作为公共数据库,对一致性要求高的数据都可以使用。
健康管理模块分析:
本模块主要供C端使用,但是目前还没有像预约,秒杀的功能,主要是内容服务。这部分我们使用mycat+innodb cluster单主(这里拿innodb cluster做个实验)。它基于组复制,一致性、扩展性方面比主从更好一些,而且还有很多集群功能。
用户模块分析:
本系统拥有较多的用户,所以用户模块单独拿出来。也是采用mycat+组复制的形式。用户这里在数据库中一定要把数据冗余做好,不然会产生很多分布式事务问题。