前言:在当今互联网时代,大数据已经成为行业发展的重要标志,海量数据的处理成为发展中无法回避的重要问题。数据量越来越大,性能要求越来越高;对于海量数据的存储,主要有两类数据库:关系型数据库和NoSQL数据库。传统数据库天然存在单机单库瓶颈,难以扩展;NoSQL产品的出现虽然弥补了传统数据库的性能问题,但并不能完全替代传统数据库。随着业务量的扩大和数据量的激增,当系统负载较重时,必须对数据进行划分。数据被分到多个分片数据库后,如果应用需要读取数据,就需要处理来自多个数据源的数据。如果没有数据库中间件(如:MyCat),那么应用将直接面对碎片化的集群,数据源切换、事务处理、数据聚合都需要应用直接处理。处理分片后的问题要花很多功夫。什么是我的猫?对于DBA:MyCat是MySqlServer增强版的存储引擎。对于软件工程师:MyCat是一个数据库服务器,MyCat可以像数据库一样操作。对于架构师:MyCat是一个强大的数据库中间件,不仅可以用于读写分离、分库分表,还可以用于多租户应用开发和云平台基础架构,让架构具有很多优点。具有很强的灵活性和适应性。MyCat的应用场景:1.支持读写分离,主从切换;2.垂直分片,水平分片;3.多租户应用。如果每个应用都有一个库,应该都只需要连接到Mycat,实现多租户;4.报表系统,处理大型报表的统计。数据分为不同的分片数据库。当应用需要读取数据时,中间件mycat可以帮助开发者进行数据聚合、事务、数据源切换等,让开发者更专注于业务开发。MyCat基本概念介绍:逻辑库(schema):对于实际应用,业务开发人员不需要知道中间件的存在,所以mycat中间件是由一个或多个数据库集群组成的逻辑库。逻辑表(table):对于应用程序来说,读写数据的表就是逻辑表。存在逻辑库对应的逻辑表。分表:指原来的大数据表,需要拆分到不同的数据库中。非分片表:对于分片表,原则上就是不需要分片的表。E-R表:基于关系型数据库中的实体-关系模型,子表和父表记录存储在同一个分片上,表分组保证数据join不会有跨库操作。全局表:类似于字典的表;一个不经常变化的表,数据量整体变化不大,大小不超过10w。分片节点(dataNode):一张大表被分成不同的分片数据库,每张表分片所在的数据库为分片节点主机(dataHost):一个或多个分片节点(dataNode)为节点主机分片规则(rule):一个大表被分成若干个分片表,需要一定的规则,让数据按照一定的业务规则分成一定的分片规则就是shardingrule。MyCat连接池解读:MyCat共享MySQL上的所有物理连接,结合了连接状态同步的特点。MyCat的连接池达到了最好的吞吐量,在一定程度上提高了整个系统的并发度。支撑能力。其中ConMap是存储连接池对象的重要数据结构。ConMap部分源码如下:privatefinalConcurrentHashMapConQueue>items=newConcurrentHashMap();publicConQueuegetSchemaConQueue(Stringschema){//根据schema获取当前分片的连接ConQueuequeue=items.get(schema);if(queue==null){//如果没有连接可用,创建一个新的ConQueuenewQueue=newConQueue();queue=items.putIfAbsent(schema,newQueue);返回(队列==null)?newQueue:queue;}returnqueue;}publicBackendConnectiontryTakeCon(finalStringschema,booleanautoCommit){finalConQueuequeue=items.get(schema);//尝试获取一个可用的使用连接BackendConnectioncon=tryTakeCon(queue,autoCommit);if(con!=null){returncon;}如果没有连接可用或者不自动模式下,为了高效充分的利用数据库连接,当用户会话需要自动提交的SQL连接时sharddn1(对应db1),连接池首先检查db1上是否有可用连接。如果是,则检查是否有自动提交模式的连接,如果找到则返回,否则返回db1上手动提交模式的连接,如果db1没有可用连接,则随机返回另一个db对应的可用连接,如果没有可用的连接并且连接池没有达到上限,则创建一个新的连接并返回。MyCat网络模型NIO/AIO:SocketConnector发起一个连接请求类,比如MyCAT与MySQL数据库的连接,都是MyCAT主动发起的。SocketAcceptor接收连接请求类,如MyCAT启动9066和8066分别监听管理员和应用程序的连接请求。SocketWR读写操作类,SocketConnector和SocketAcceptor只负责socket的建立,当socket连接建立后,字节读写操作由SocketWR完成。在MyCAT中,NIO采用了多反应器模式,内部维护了一个Selector分别处理不同的事件。例如NIOConnector类-选择器事件选择器。connectQueue需要建立连接的对象临时放在这个队列reactorPool中,当连接建立时,从reactorPool中分配一个NIORactor来处理Read和Write事件connect源码解读:privatevoidconnect(Selectorselector){AbstractConnectionc=null;while((c=connectQueue.poll())!=null){尝试{SocketChannelchannel=(SocketChannel)c.getChannel();channel.register(selector,SelectionKey.OP_CONNECT,c);channel.connect(newInetSocketAddress(c.host,c.port));}catch(Exceptione){LOGGER.error("error:",e);c.close(e.toString());}}//处理connect事件,移交ProcessprivatevoidfinishConnect(SelectionKeykey,Objectatt){BackendAIOConnectionc=(BackendAIOConnection)att;尝试{if(finishConnect(c,(SocketChannel)c.channel)){clearSelectionKey(key);c.setId(ID_GENERATOR.getId());NIOProcessor处理器=MycatServer.getInstance().nextProcessor();c.setProcessor(处理器);NIOReactorreactor=reactorPool.getNextReactor();reactor.postRegister(c);c.onConnectfinish();}}catch(Exceptione){clearSelectionKey(key);LOGGER.error("错误:",e);c.close(e.toString());c.onConnectFailed(e);}}判断connectQueue中是否有新的连接请求建立SocketChannel。在选择器中注册OP_CONNECT。启动SocketChannel.connect()操作。MyCat读写分离实践:在一些大型网站业务场景中,单一数据库提供的并发度已经不能满足业务需求;为了提供数据库的并发性和负载能力,一般通过读写分离来实现。当我们的数据库实现读写分离后,需要在应用中切换数据源。MyCat可以帮助我们更好的实现数据源的动态切换,即应用程序只需要连接到MyCat中间件,自动动作帮我们读写数据库。未采用MyCat中间件项目架构:采用MyCat中间件架构:两者的区别:图一要求在应用中配置多个数据源,多个数据源可以根据不同的业务需求动态切换。应用通过MyCat后,只需要连接MyCat作为数据源即可,方便扩展,不影响已有程序。搭建主从:jdk准备:jdk1.7及以上版本mysql准备,两个mysql服务,一个作为主库负责写入数据,一个负责从数据库读取数据MyCat安装:MyCAT提供编译安装packages,Mycat-server-xxxxx.linux.tar.gz解压MyCat相关目录说明:bin程序目录,进入bin目录:Linux下运行:./mycatconsole,首先存放在chmod+x*conf目录下配置文件,server.xml是Mycat服务端参数调整和用户授权的配置文件,schema.xml是逻辑库定义、表和分片定义的配置文件,rule.xml是分片规则的配置文件,具体shardingrules的参数信息单独存储为一个文件,version.txtlib目录主要存放mycat依赖的一些jar文件。日志存放在logs/mycat.log中,每天一个文件,日志配置在conf/log4j.xml中。可以根据自己的需要,调整输出电平进行调试。在debug级别,会输出更多的信息,方便排查问题。配置schema.xml逻辑库、逻辑表、分片:"localhost1"maxCon="1000"minCon="10"balance="0"writeType="0"dbType="mysql"dbDriver="jdbc"switchType="1"slaveThreshold="100">at>selectuser()writeHost>readHost>dataHost>Configureserver.xml,主要配置MyCat连接的逻辑库和逻辑表访问权限的配置:123456TESTDB_YONGTESTDB_YONG读写分离测试:准备两台mysql服务器,一台配置为主库,负责数据写入,一台配置为从库,负责数据读取数据库中间件MyCat通过shcemal.xml和server配置两个数据库的读写。xml。启动MyaCat服务,连接mycat切换读写分离数据源:mysql-h127.0.0.1-P8066-uroot-p连接成功后,业务开发者就可以像操作数据库一样使用mycat了。配置的路由规则执行数据的分片、存储和聚合。通过MyCat插入数据:insertintotest(id,name)value(1,'wyw');QueryOK,1rowaffected(0.05sec)检查主从数据库是否有数据,访问数据:select*fromtestwhereid=1;±-----+|id|±-----+|1|±-----+1rowsinset(0.00sec)根据MyCat的运行日志,查看读写分离本质:mycat/logs/mycat.log从服务器上查询命令: