作为Mycat核心开发者,怎能不来一波Mycat系列文章?
写在前面
Mycat是基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得Mycat一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到Mycat的基因中,使得Mycat在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。——来自Mycat官网。
作为Mycat的核心开发者,怎能不来一波Mycat系列文章呢?
背景介绍
作为Mycat的核心开发者之一,今天,终于安排到Mycat系列文章了。在Mycat系列文章中,我们一起从一个利用Mycat实现分库分表的案例作为入门程序。后续会持续更新Mycat原理、架构和底层源码解析的文章。希望Mycat系列文章能够帮助小伙伴们彻底掌握Mycat。
那么,今天,我们就先来一波使用Mycat实现MySQL分库分表的文章。
注:案例中的MySQL服务器是安装在CentOS6.8服务器上,Mycat Server是安装在本机的Windows系统上,安装在什么环境上无所谓,这里,我用的是VMWare虚拟机,安装的CentOS系统,开启多个虚拟机,电脑实在是吃力,所以将Mycat Server装在了本机的Windows系统上。
方案规划
IP | 端口 | 服务 | 用户名 | 密码 |
---|---|---|---|---|
192.168.81.131 | 3306 | MySQL数据库 | root | root |
192.168.81.132 | 3306 | MySQL数据库 | root | root |
192.168.81.133 | 3306 | MySQL数据库 | root | root |
192.168.81.130 | 8066/9066 | Mycat Server | admin | admin123 |
如上表所示,在局域网的4台主机中,131——133的主机各安装有一台MySQL实例,130主机,也就是本机安装了Mycat Server。
现在假设系统的数据库为messagedb,里面只有2张表,一张表为消息表:message,一张表示消息来源的字典表:source,本案例实现的是按自然月分片的规则,因此上述3个mysql实例各自需要创建4个数据库,即
数据库实例 | 存储的数据库 |
---|---|
192.168.81.131:3306 | message202001、message202002、message202003、message202004 |
192.168.81.132:3306 | message202005、message202006、message202007、message202008 |
192.168.81.133:3306 | message202009、message202010、message202011、message202012 |
说明:如果是刚接触Mycat的小伙伴对分片不太理解,简单地说,对于Mycat,一个分片表示某一个MySQL实例上的某一个数据库,即schema@host,于是当我们原先的一张大表需要分片的时候,mycat就会按照我们设定的规则,把这张大表中的数据分散到各个分片上,即所谓的分表分库,因此我们需要在每个对应的分片上创建相同名称的数据库,相同结构的表。
环境准备
注意:这里,我就省略了MySQL的安装过程,小伙伴们可自行安装MySQL。我后续也会在MySQL相关的专题中给大家分享企业级MySQL安装、优化与部署过程。
创建数据库并建表导入数据
根据数据库实例和存储的数据库对应关系表创建所有的数据库,并在每个数据库里执行如下脚本:
create table source (
id int(11) not null auto_increment primary key comment 'pk',
name varchar(10) default '' comment 'source name'
);
create table message (
id int(11) not null auto_increment primary key comment 'pk',
content varchar(255) default '' comment 'message content',
create_time date default null,
source_id int(11) not null,
foreign key(source_id) references source(id)
);
insert into `source`(`id`,`name`) values(1,'weibo');
insert into `source`(`id`,`name`) values(2,'weixin');
insert into `source`(`id`,`name`) values(3,'qq');
insert into `source`(`id`,`name`) values(4,'email');
insert into `source`(`id`,`name`) values(5,'sms');
在message表中,总共有4个字段:
- id:主键
- content:消息的内容
- create_time:创建时间,这也是mycat进行分片时的参考字段
- source_id:source表的外键
另外,我们在source表插入了5条记录,用于测试。到这里,后端数据库的环境就搭建完成了。
安装和配置Mycat
安装Mycat
安装Mycat的过程比较简单,在这个地址就可以下载安装包:https://github.com/MyCATApache/Mycat-download/tree/master/1.6-RELEASE。下载完之后,就进行解压到系统相应目录,这里就不细说了。
Mycat安装包结构
安装完之后,简单地看一下mycat目录结构:
启动Mycat
WIndows下启动需要以管理员身份打开命令行窗口,cd 到Mycat的bin目录下,或者将Mycat的 安装目录加入系统的环境变量path目录里,首先输入命令mycat install进行mycat服务的安装操作,然后 输入命令mycat start 启动Mycat Server。
Linux下进入Mycat的bin目录直接输入./mycat start 启动Mycat Server。
Mycat提供了两个端口,其中,9066端口是管理端口,提供查看当前系统节点的情况,报告心跳状态等相关系统监控的功能,8066是数据端口,相当于数据库的访问端口。我们可以使用mysql命令访问这里两个端口
mysql -h[mycat_host] -u[mycat_user] -p[mycat_passwd] -P [8066|9066]
同时,我们也可以修改这两个端口。
那么mycat_user和mycat_passwd是如何配置呢,下面就需要介绍mycat中最主要的3个配置文件:server.xml,schema.xml和rule.xml。
server.xml
该配置文件是用于配置mycat的系统信息,主要有两个标签:system和user。这里的user就是上述访问mycat服务的用户,不是后端数据库的用户。如果我们使用默认的配置,server.xml大概是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="useSqlStat">0</property>
<property name="useGlobleTableCheck">0</property>
<property name="sequnceHandlerType">2</property>
<property name="processorBufferPoolType">0</property>
<property name="useOffHeapForMerge">1</property>
<property name="memoryPageSize">1m</property>
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<property name="systemReserveMemorySize">384m</property>
</system>
<user name="admin">
<property name="password">admin123</property>
<property name="schemas">messagedb</property>
</user>
</mycat:server>
user标签下schemas属性表示该用户可以访问的数据库,可以定义多个数据库,用英文逗号隔开。schemas定义的数据库,一定要配置在后面的schema.xml文件对应的逻辑库,否则会提示无法访问。
schema.xml
schema配置文件比较复杂,也是最关键的一个配置文件,定义了mycat中的逻辑库、逻辑表,和分片的相关信息。配置如下:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="messagedb" checkSQLschema="false" sqlMaxLimit="100">
<table name="message" dataNode="dn1,dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9,dn10,dn11,dn12" rule="sharding-by-month" />
<table name="source" primaryKey="id" type="global" dataNode="dn1,dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9,dn10,dn11,dn12" />
</schema>
<dataNode name="dn1" dataHost="mysql-01" database="message202001" />
<dataNode name="dn2" dataHost="mysql-01" database="message202002" />
<dataNode name="dn3" dataHost="mysql-01" database="message202003" />
<dataNode name="dn4" dataHost="mysql-01" database="message202004" />
<dataNode name="dn5" dataHost="mysql-02" database="message202005" />
<dataNode name="dn6" dataHost="mysql-02" database="message202006" />
<dataNode name="dn7" dataHost="mysql-02" database="message202007" />
<dataNode name="dn8" dataHost="mysql-02" database="message202008" />
<dataNode name="dn9" dataHost="mysql-03" database="message202009" />
<dataNode name="dn10" dataHost="mysql-03" database="message202010" />
<dataNode name="dn11" dataHost="mysql-03" database="message202011" />
<dataNode name="dn12" dataHost="mysql-03" database="message202012" />
<dataHost name="mysql-01" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.81.131:3306" user="root"
password="root">
</writeHost>
</dataHost>
<dataHost name="mysql-02" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM2" url="192.168.81.132:3306" user="root"
password="root">
</writeHost>
</dataHost>
<dataHost name="mysql-03" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM3" url="192.168.81.133:3306" user="root"
password="root">
</writeHost>
</dataHost>
</