文章共 1796字,阅读大约须要 4分钟 !
在现在海量数据充斥的互联网环境下,分库分表的意义我想在此处就不用赘述了。而分库分表目前流行的方案最起码有两种:mysql
而本文即将要实验的 MyCAT框架就属于第二种方案的表明做品。linux
注: 本文首发于 My Personal Blog:CodeSheep·程序羊,欢迎光临 小站
在本文中,我拿出了三台 Linux主机投入试验,各节点的角色分配以下表所示:git
节点 | 部署组件 | 角色 | |
---|---|---|---|
192.168.199.75 | MySQL 、 MyCAT | master | |
192.168.199.74 | MySQL | slave | |
192.168.199.76 | MySQL | standby master |
若是说上面这张表不足以说明实验模型,那接下来再给一张图好了,以下所示:github
我想这样看来的话,各个节点布了哪些组件,节点间的角色关系应该一目了然了吧sql
实验环境规划好了之后,接下来进行具体的部署与实验过程,首先固然是 MyCAT代理的部署
关于该部分,网上教程实在太多了,但最好仍是参考官方文档来吧,下面也简述一下部署过程数据库
这里安装的是 MyCAT 1.5后端
wget https://raw.githubusercontent.com/MyCATApache/Mycat-download/master/1.5-RELEASE/Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz tar -zxvf Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz mv mycat /usr/local/
./mycat start
mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB
官网上对于这一部分的描述是很是详细的,MyCAT 配置主要涉及三个 XML配置文件:框架
server.xml
:MyCAT框架的系统参数/用户参数配置文件schema.xml
: MyCAT框架的逻辑库表与分片的配置文件rule.xml
:MyCAT框架的逻辑库表分片规则的配置文件用以下图形能够形象地表示出这三个 XML配置文件的配置内容和相互关系:学习
下面来进入具体的实验环节 ,这也是围绕 MyCAT提供的几大主要功能展开的,主要涉及三个方面测试
实验以前,咱们先给出公共的 server.xml
文件的配置,这部分后续实验过程当中并不修改,其也就是定义了系统参数和用户参数:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://org.opencloudb/"> <system> <property name="defaultSqlParser">druidparser</property> <!-- <property /> 这块诸多的property配置在此就不配置了,参照官网按需配置 --> </system> <user name="test"> <property name="password">test</property> <property name="schemas">TESTDB</property> </user> <user name="user"> <property name="password">user</property> <property name="schemas">TESTDB</property> <property name="readOnly">true</property> </user> </mycat:server>
预期实验效果:经过 MyCAT代理往一张逻辑表中插入的多条数据,在后端自动地分配在不一样的物理数据库表上
咱们按照本文 第二节【环境规划】中给出的实验模型图来给出以下的 MyCAT逻辑库配置文件 `
schema.xml 和 分库分表规则配置文件
rule.xml`
schema.xml
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/" > <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> <table name="travelrecord" dataNode="dn1,dn2" rule="sharding-by-month" /> </schema> <dataNode name="dn1" dataHost="testhost" database="db1" /> <dataNode name="dn2" dataHost="testhost" database="db2" /> <dataHost name="testhost" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="localhost:3306" user="root" password="xxxxxx"> <readHost host="hostS1" url="192.168.199.74:3306" user="root" password="xxxxxx" /> </writeHost> <writeHost host="hostM2" url="192.168.199.76:3306" user="root" password="xxxxxx"> </writeHost> </dataHost> </mycat:schema>
其中定义了实验用到的 hostM一、hostS1 和 hostM2
rule.xml
<tableRule name="sharding-by-month"> <rule> <columns>create_date</columns> <algorithm>partbymonth</algorithm> </rule> </tableRule> <function name="partbymonth" class="org.opencloudb.route.function.PartitionByMonth"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sBeginDate">2018-11-01</property> </function>
这里配置了sharding-by-month
的分库分表规则,即按照表中的create_date
字段进行分割,从2018-11-01
日期开始,月份不一样的数据落到不一样的物理数据库表中
create database db1; create database db2;
mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB
travelrecord
create table travelrecord (id bigint not null primary key,city varchar(100),create_date DATE);
travelrecord
表中插入两条数据insert into travelrecord(id,city,create_date) values(1,'NanJing','2018-11-3'); insert into travelrecord(id,city,create_date) values(2,'BeiJing','2018-12-3');
因为插入的这两条记录的 create_date
分别是 2018-11-3
和 2018-12-3
,而咱们配的分库分表的规则便是根据 2018-11-01
这个日期为起始来进行递增的,按照前面咱们配的分片规则,理论上这两条记录按照 create_date
日期字段的不一样,应该分别插入到 hostM1的 db1和 db2两个不一样的数据库中。
因为 hostM1和 hostS1组成了 主-从库 关系,所以刚插入的两条数据也应该相应自动同步到 hostS1的 db1和 db2两个数据库中,不妨也来验证一下:
预期实验效果:开启了 MyCAT的读写分离机制后,读写数据操做各行其道,互不干扰
此节实验用到的配置文件 schema.xml
和 rule.xml
基本和上面的【分库分表】实验没什么不一样,只是咱们须要关注一下 schema.xml
配置文件中 <dataHost />
标签里的 balance
字段,它是与读写分离息息相关的配置:
所以咱们就须要弄清楚 <dataHost /> 标签中 balance参数的含义:
balance="0"
:不开启读写分离机制,即读请求仅分发到 writeHost上balance="1"
:读请求随机分发到当前 writeHost对应的 readHost和 standby writeHost上balance="2"
:读请求随机分发到当前 dataHost内全部的 writeHost / readHost上balance="3"
:读请求随机分发到当前 writeHost对应的 readHost上咱们验证一下 balance="1"
的状况,即开启读写分离机制,且读请求随机分发到当前 writeHost对应的 readHost和 standby writeHost上,而对于本文来说,也即:hostS1 和 hostM2 上
咱们来作两次数据表的 SELECT
读操做:
mysql> select * from travelrecord limit 6; +----+----------+-------------+ | id | city | create_date | +----+----------+-------------+ | 3 | TianJing | 2018-11-04 | | 5 | ShenYang | 2018-11-05 | | 4 | Wuhan | 2018-12-04 | | 6 | Harbin | 2018-12-05 | +----+----------+-------------+ 4 rows in set (0.08 sec) mysql> select * from travelrecord limit 6; +----+---------+-------------+ | id | city | create_date | +----+---------+-------------+ | 2 | BeiJing | 2018-12-03 | | 8 | WuXi | 2018-12-06 | | 1 | NanJing | 2018-11-03 | | 7 | SuZhou | 2018-11-06 | +----+---------+-------------+ 4 rows in set (0.01 sec)
而后咱们取出 mycat.log
日志查看一下具体详情,咱们发现第一次 select
读操做分发到了 hostM2
上:
而第二次 select
读操做分发到了 hostS1
上:
预期实验效果:开启 MyCAT的主备机制后,当主库宕机时,自动切换到备用机进行操做
关于主备切换,则须要弄清楚 <dataHost />
标签中 switchType
参数的含义:
switchType="-1"
:不自动切换主备数据库switchType="1"
:自动切换主备数据库switchType="2"
:基于MySQL主从复制的状态来决定是否切换,需修改heartbeat语句:show slave status
switchType="3"
:基于Galera(集群多节点复制)的切换机制,需修改heartbeat语句:show status like 'wsrep%'
此处验证一下 Mycat的主备自动切换效果。为此首先咱们将 switchType="-1"
设置为 switchType="1"
,并重启 MyCat服务:
<dataHost name="testhost" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
在本实验环境中,在 hostM1 和 hostM2均正常时,默认写数据时是写到 hostM1的
systemctl stop mysqld.service
接下来再经过 MyCat插入以下两条数据:
insert into travelrecord(id,city,create_date) values(3,'TianJing','2018-11-4'); insert into travelrecord(id,city,create_date) values(4,'Wuhan','2018-12-4');
效果以下:
insert into travelrecord(id,city,create_date) values(5,'ShenYang','2018-11-5'); insert into travelrecord(id,city,create_date) values(6,'Harbin','2018-12-5');
再插入两条数据:
insert into travelrecord(id,city,create_date) values(7,'SuZhou','2018-11-6'); insert into travelrecord(id,city,create_date) values(8,'WuXi','2018-12-6');
很明显,答案是确定的
因为能力有限,如有错误或者不当之处,还请你们批评指正,一块儿学习交流!