这期内容当中小编将会给大家带来有关MyCat中怎么实现读写分离,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

1、mycat实现读写分离

这里没有用到mysql03主机,读写分离的实现比较简单,只需要修改mycat的下面两个配置文件即可。如下:

1)修改server.xml文件

[root@mycatmycat]#pwd/usr/local/mycat<!--此处为mycat的家目录-->[root@mycatmycat]#vimconf/server.xml<!--指定client连接mycat的用户名及密码,此处的账号密码与MySQL数据库无关-->[root@mycatmycat]#vimconf/server.xml<!--定位到80行左右,修改如下--><username="mycat"defaultAccount="true"><!--mycat为用户名--><propertyname="password">pwd@123</property><!--此处为用户mycat的登录密码--><propertyname="schemas">test_mycat</property><!--此处为逻辑库名--<!--表级DML权限设置--><!--<privilegescheck="false"><schemaname="TESTDB"dml="0110"><tablename="tb01"dml="0000"></table><tablename="tb02"dml="1111"></table></schema></privileges>--></user>2)修改schema.xml文件

<?xmlversion="1.0"?><!DOCTYPEmycat:schemaSYSTEM"schema.dtd"><mycat:schemaxmlns:mycat="http://io.mycat/"><!--下面的schema必须和第一个文件中的schemaname(逻辑库名)一致。--><schemaname="test_mycat"checkSQLschema="false"sqlMaxLimit="100"dataNode="dn1"></schema><dataNodename="dn1"dataHost="host1"database="test"/><!--这里的database是指定要连接后端的哪个数据库,这里连接的是test库--><!--下面是指定后端真实的MySQL主机,关于下面的balance值,有三个可选值,将在下面写下来--><dataHostname="host1"maxCon="1000"minCon="10"balance="3"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><!--指定后端哪台主机用来写数据--><writeHosthost="hostM1"url="192.168.20.2:3306"user="root"password="123.com"><!--canhavemultireadhosts--><!--指定后端哪台主机用来读数据--><readHosthost="hostS2"url="192.168.20.3:3306"user="root"password="123.com"/></writeHost></dataHost></mycat:schema>

注:上面提到的dataHost字段balance负载均衡类型,目前的取值有以下4 种:

balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上(默认值)。

balance="1",全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。

balance="2",所有读操作都随机的在 writeHost、readhost 上分发。

balance="3",所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有。

writeTyep字段有以下3中取值:

1、writeType="0", 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个 writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties 。
2、writeType="1",所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。switchType 属性

-1 表示不自动切换。

1 默认值,自动切换。

2 基于 MySQL 主从同步的状态决定是否切换。

修改后的完整配置文件如下(为避免冗余,删除了部分注释):server.xml配置文件内容如下:

[root@mycatmycat]#vimconf/server.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmycat:serverSYSTEM"server.dtd"><mycat:serverxmlns:mycat="http://io.mycat/"><system><propertyname="useSqlStat">0</property><!--1为开启实时统计、0为关闭--><propertyname="useGlobleTableCheck">0</property><!--1为开启全加班一致性检测、0为关闭--><propertyname="sequnceHandlerType">2</property><propertyname="processorBufferPoolType">0</property><propertyname="handleDistributedTransactions">0</property><propertyname="useOffHeapForMerge">1</property><propertyname="memoryPageSize">1m</property><propertyname="spillsFileBufferSize">1k</property><propertyname="useStreamOutput">0</property><propertyname="systemReserveMemorySize">384m</property><propertyname="useZKSwitch">true</property></system><username="mycat"><propertyname="password">pwd@123</property><propertyname="schemas">test_mycat</property></user></mycat:server>schema.xml配置文件内容如下:

[root@mycatmycat]#vimconf/schema.xml<?xmlversion="1.0"?><!DOCTYPEmycat:schemaSYSTEM"schema.dtd"><mycat:schemaxmlns:mycat="http://io.mycat/"><schemaname="test_mycat"checkSQLschema="false"sqlMaxLimit="100"dataNode="dn1"></schema><dataNodename="dn1"dataHost="host1"database="test"/><dataHostname="host1"maxCon="1000"minCon="10"balance="3"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><writeHosthost="hostM1"url="192.168.20.2:3306"user="root"password="123.com"><!--canhavemultireadhosts--><readHosthost="hostS2"url="192.168.20.3:3306"user="root"password="123.com"/></writeHost></dataHost></mycat:schema>

注:至此,后端数据库上自行创建有相关权限的用户,比如我在上面的datahost字段中指定的writehost和readhost字段的user值为root,则数据库的root账号要有对应的登录权限(默认root用户只允许在localhost登录,所以要自行修改root权限或换成其他有权限的用户)。

总结:
1.指定的后端数据库登录用户,必须可以有相应的权限;
2.在上面指定的后端真实数据库为test,所以后端必须要有这个test库;

3)启动mycat并测试读写分离效果

[root@mycatmycat]#mycatstart#启动mycat[root@mycatmycat]#mysql-umycat-ppwd@123-h192.168.20.4-P8066#登录到mycat#192.168.20.4为mycat主机IP,mycat监听端口为8066,使用的登录用户为server.xml文件中创建的用户#创建表并插入一些测试数据mysql>usetest_mycat;mysql>createtablet1(idint,namevarchar(4));mysql>insertintot1values(1,'张三'),(2,'李四'),(3,'王五');#此时,去后端数据库上查看,应该是有上面这些数据的。#现在可以暂时关闭后端数据库的主从复制,然后再mycat主机上继续插入数据,测试是否可以读到#关闭主从复制命令:stopslave;#以下操作还是在mycat主机进行mysql>insertintot1values(4,'赵六');#插入一条数据QueryOK,1rowaffected(0.01sec)mysql>select*fromt1;#查询不到刚插入的数据,说明读写操作没有在同一台主机上进行+------+--------+|id|name|+------+--------+|1|张三||2|李四||3|王五|+------+--------+#可以去后端两个数据库分别进行查看数据#mysql01主机的数据如下(说明写操作是在mysql01):mysql>select*fromt1;+------+--------+|id|name|+------+--------+|1|张三||2|李四||3|王五||4|赵六|+------+--------+4rowsinset(0.00sec)#mysql02主机的数据如下:mysql>select*fromt1(说明读操作是在mysql02);+------+--------+|id|name|+------+--------+|1|张三||2|李四||3|王五|+------+--------+3rowsinset(0.00sec)

读写分离效果至此结束。(为不影响后面的测试进行,最好恢复mysql01和mysql02主机的主从复制)。

2、mycat实现分库

一个数据库由很多表组成,每个表对应着不同的业务,所谓分库,就是按照业务将表进行分类,分不到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,分库的原则:有紧密关联关系的表应该在一个库里,相互没有或者关联关系不大的表可以分到不同的库里。

分库举例:

假设现在有四张表: customer, orders, orders_detail, dict_order_type,每张表都有数百万条数据,那么这四张表如若要实现分库,则可以将customer表单独分离到一个数据库,另外三张表单独在另一个数据库。

1)修改server.xml文件(就改了一下逻辑库名)

[root@mycatmycat]#catconf/server.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmycat:serverSYSTEM"server.dtd"><mycat:serverxmlns:mycat="http://io.mycat/"><system><propertyname="useSqlStat">0</property><!--1为开启实时统计、0为关闭--><propertyname="useGlobleTableCheck">0</property><!--1为开启全加班一致性检测、0为关闭--><propertyname="sequnceHandlerType">2</property><propertyname="processorBufferPoolType">0</property><propertyname="handleDistributedTransactions">0</property><propertyname="useOffHeapForMerge">1</property><propertyname="memoryPageSize">1m</property><propertyname="spillsFileBufferSize">1k</property><propertyname="useStreamOutput">0</property><propertyname="systemReserveMemorySize">384m</property><propertyname="useZKSwitch">true</property></system><username="mycat"><propertyname="password">pwd@123</property><propertyname="schemas">test_db</property></user></mycat:server>2)修改schema.xml文件

[root@mycatmycat]#catconf/schema.xml<?xmlversion="1.0"?><!DOCTYPEmycat:schemaSYSTEM"schema.dtd"><mycat:schemaxmlns:mycat="http://io.mycat/"><schemaname="test_db"checkSQLschema="false"sqlMaxLimit="100"dataNode="dn1"><tablename="customer"dataNode="dn2"/><!--这里指定customer在dn2节点上--></schema><dataNodename="dn1"dataHost="host1"database="test"/><dataNodename="dn2"dataHost="host2"database="test"/><dataHostname="host1"maxCon="1000"minCon="10"balance="3"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><writeHosthost="hostM1"url="192.168.20.2:3306"user="root"password="123.com"><!--canhavemultireadhosts--><readHosthost="hostS2"url="192.168.20.3:3306"user="root"password="123.com"/></writeHost></dataHost><!--下面添加host2主机字段,指定的主机就是mysql03--><dataHostname="host2"maxCon="1000"minCon="10"balance="0"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><writeHosthost="hostM2"url="192.168.20.21:3306"user="root"password="123.com"></writeHost></dataHost></mycat:schema>3)重启mycat

[root@mycatmycat]#mycatrestart

注:后端指定的真实数据库必须要有test数据库,因为在上面schema.xml文件中的dataNode字段指定的是连接后端的test数据库。

4)测试分库效果

#登录到mycat[root@mycatmycat]#mysql-umycat-ppwd@123-h192.168.20.4-P8066#创建相应的表mysql>usetest_db;mysql>CREATETABLEcustomer(->id_aINTAUTO_INCREMENT,->NAMEVARCHAR(200),->PRIMARYKEY(id_a)->);QueryOK,0rowsaffected(0.02sec)mysql>CREATETABLEorders(->id_bINTAUTO_INCREMENT,->order_typeINT,->customer_idINT,->amountDECIMAL(10,2),->PRIMARYKEY(id_b)->);QueryOK,0rowsaffected(0.01sec)mysql>CREATETABLEorders_detail(->id_cINTAUTO_INCREMENT,->detailVARCHAR(2000),->order_idINT,->PRIMARYKEY(id_c)->);QueryOK,0rowsaffected(0.02sec)mysql>CREATETABLEdict_order_type(->id_dINTAUTO_INCREMENT,->order_typeVARCHAR(200),->PRIMARYKEY(id_d)->);QueryOK,0rowsaffected(0.01sec)#登录到后端数据库上,查看表是否按照预计的效果拆分[root@mycatmycat]#mysql-uroot-p123.com-h192.168.20.2mysql>usetest;mysql>showtables;#可以看到主机mysql01这里有三个表+-----------------+|Tables_in_test|+-----------------+|dict_order_type||orders||orders_detail|+-----------------+3rowsinset(0.00sec)#登录到mysql03上查看[root@mycatmycat]#mysql-uroot-p123.com-h192.168.20.21mysql>usetest;mysql>showtables;#可以看到这里只有customer表+----------------+|Tables_in_test|+----------------+|customer|+----------------+1rowinset(0.00sec)

至此,已经实现了分库,多个表放在了不同的库中(在上面的栗子中,实现的是多个表放在了不同的主机上),但对于通过mycat登录的客户来说,还是一个库,库中有四张表。

3、mycat实现分表

这里对一个新表emp进行拆分。

1)schema.xml文件修改如下(完整配置文件)

[root@mycatmycat]#catconf/schema.xml<?xmlversion="1.0"?><!DOCTYPEmycat:schemaSYSTEM"schema.dtd"><mycat:schemaxmlns:mycat="http://io.mycat/"><schemaname="test_db"checkSQLschema="false"sqlMaxLimit="100"dataNode="dn1"><tablename="customer"dataNode="dn2"/><!--只需要在原来的配置文件中增加下面一行即可,表示将emp表分在了dn1和dn2这两个节点上--><tablename="emp"dataNode="dn1,dn2"rule="mod_rule"/></schema><dataNodename="dn1"dataHost="host1"database="test"/><dataNodename="dn2"dataHost="host2"database="test"/><dataHostname="host1"maxCon="1000"minCon="10"balance="3"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><writeHosthost="hostM1"url="192.168.20.2:3306"user="root"password="123.com"><!--canhavemultireadhosts--><readHosthost="hostS2"url="192.168.20.3:3306"user="root"password="123.com"/></writeHost></dataHost><dataHostname="host2"maxCon="1000"minCon="10"balance="0"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><writeHosthost="hostM2"url="192.168.20.21:3306"user="root"password="123.com"></writeHost></dataHost></mycat:schema>2)rule.xml文件添加以下内容

[root@mycatmycat]#vimconf/rule.xml#修改rule.xml文件<tableRulename="mod_rule"><!--这里指定的name必须和schema.xml中指定的name一致--><rule><columns>id</columns><!--这里指定的是以哪里列进行分表的--><algorithm>mod_long</algorithm><!--这里指定的是分片方法--></rule></tableRule>...................<!--下面的name必须和上面的分片方法一致--><functionname="mod_long"class="io.mycat.route.function.PartitionByMod"><!--howmanydatanodes--><propertyname="count">2</property><!--这里指定的是node节点数量--></function>3)重启mycat并登录到mycat

[root@mycatmycat]#mycatrestart4)登录到mycat插入数据进行测试分表效果

[root@mycatmycat]#mysql-umycat-ppwd@123-h192.168.20.4-P8066mysql>usetest_db;#创建emp表(后端两个数据库节点上都会有这张表)mysql>createtableemp(->idint,->namevarchar(10)->);QueryOK,0rowsaffected(0.41sec)#插入多条数据(对于这种分表,插入数据需要指定列名,否则会报错)mysql>insertintoemp(id,name)values(1,'张三'),(2,'李四'),(3,'王五'),(4,'赵六');#查询新插入的数据mysql>select*fromemp;+------+--------+|id|name|+------+--------+|2|李四||4|赵六||1|张三||3|王五|+------+--------+4rowsinset(0.04sec)mysql>select*fromemporderbyid;#对结果进行排序+------+--------+|id|name|+------+--------+|1|张三||2|李四||3|王五||4|赵六|+------+--------+4rowsinset(0.01sec)#后端mysql01主机查询到该表的数据如下:mysql>select*fromemp;+------+--------+|id|name|+------+--------+|2|李四||4|赵六|+------+--------+2rowsinset(0.00sec)#mysql03主机查询到的数据如下:mysql>select*fromemp;+------+--------+|id|name|+------+--------+|1|张三||3|王五|+------+--------+2rowsinset(0.00sec)

可以看到数据是平均分散在不同节点上保存的。

但是经过分片的普通表,是无法直接和其他表进行join的。

要想解决多表join的问题,还需要修改schema.xml配置文件,在分表的table字段下添加childTable字段,具体怎么实现,还在研究中。但是可以将分表的类型设置为全局表,这是一种比较简单的实现方式。

3、全局表

分表后,与其他表如何join就成了比较棘手的问题,我们可以选择将分表设置为全局表,这是一个解决join的方法(但不是唯一的方法),但全局表有一定的局限性,如下:

全局表变动不频繁;

数据量总体变化不大;

数据规模不大,很少有超数十万的记录。

全局表有以下特性:

全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性;

全局表的查询操作,只从一个节点获取;

全局表可以跟任何一个表进行 JOIN 操作。

若想创建全局表,只需在table字段增加type="global"即可。如下:

1)定义全局表

[root@mycatconf]#catschema.xml<?xmlversion="1.0"?><!DOCTYPEmycat:schemaSYSTEM"schema.dtd"><mycat:schemaxmlns:mycat="http://io.mycat/"><schemaname="test_db"checkSQLschema="false"sqlMaxLimit="100"dataNode="dn1"><tablename="customer"dataNode="dn2"/><!--在下面的table字段增加global属性即可--><tablename="emp"dataNode="dn1,dn2"type="global"></table></schema><dataNodename="dn1"dataHost="host1"database="test"/><dataNodename="dn2"dataHost="host2"database="test"/><dataHostname="host1"maxCon="1000"minCon="10"balance="3"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><writeHosthost="hostM1"url="192.168.20.2:3306"user="root"password="123.com"><!--canhavemultireadhosts--><readHosthost="hostS2"url="192.168.20.3:3306"user="root"password="123.com"/></writeHost></dataHost><dataHostname="host2"maxCon="1000"minCon="10"balance="0"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><heartbeat>selectuser()</heartbeat><!--canhavemultiwritehosts--><writeHosthost="hostM2"url="192.168.20.21:3306"user="root"password="123.com"></writeHost></dataHost></mycat:schema>2)验证全局表

mysql>droptableemp;#需要删除之前创建的emp表QueryOK,0rowsaffected(0.03sec)#重新创建emp表mysql>createtableemp(->idint,->namevarchar(10)->);QueryOK,0rowsaffected(0.38sec)#插入数据测试mysql>insertintoemp(id,name)values(1,'张三'),(2,'李四'),(3,'王五'),(4,'赵六');#在mycat上查询插入的数据如下:mysql>select*fromemp;+------+--------+|id|name|+------+--------+|1|张三||2|李四||3|王五||4|赵六|+------+--------+4rowsinset(0.02sec)#在后端主机上分别查看emp表中的数据:#mysql01主机上数据如下:mysql>select*fromemp;+------+--------+|id|name|+------+--------+|1|张三||2|李四||3|王五||4|赵六|+------+--------+4rowsinset(0.00sec)#mysql03主机上数据如下:mysql>select*fromemp;+------+--------+|id|name|+------+--------+|1|张三||2|李四||3|王五||4|赵六|+------+--------+4rowsinset(0.00sec)

上述就是小编为大家分享的MyCat中怎么实现读写分离了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。