MyCat 介绍及分表测试
MyCat 介绍及分表测试
官方 http://www.mycat.org.cn/
github https://github.com/MyCATApache/Mycat-Server
1.简介
1.1 什么是MYCAT
MyCat 是流行的基于 java 语言编写的数据库中间件,是一个实现了 MySQL 协议的服务器,前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和命令行访问,而其后端可以用 MySQL 原生协议与多个 MySQL 服务器通信,也可以用 JDBC 协议与大多数主流数据库服务器通信,其核心功能是分库分表。配合数据库的主从模式还可实现读写分离。
MyCat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。MyCat是代理,MyCat后面就是物理数据库。和Web服务器的 Nginx类似。对于使用者来说,访问的都是 MyCat,不会接触到后端的数据库。
MyCat特性:
- 支持SQL92标准
- 支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常见SQL语法
- 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理。
- 基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluste
- 支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
- 基于Nio实现,有效管理线程,解决高并发问题。
- 支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页。
- 支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join。
- 支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。
1.2 MYCAT架构
1.3 名词概念
名词 | 说明 |
---|---|
逻辑库 (schema) | 数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库 |
逻辑表(table) | 分布式数据库中,对应用来说,读写数据的表就是逻辑表。 |
分片表 | 每个分片都有一部分数据,所 有分片构成了完整的数据. eg |
非分片表 | 非分片是相对分片表来说的,就是那 些不需要进行数据切分的表,eg. |
数据主机 dataHost | 主机地址.可以使用主机名,IP,域名定义. |
分片节点(dataNode) | 一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点 (dataNode ) |
分片规则(rule) | 1个大表被分成若干个分片表,需要的规则 |
多租户 | 多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性。 |
ER 表 | ER表示(Entity-Relationship Model)描述了真实世界中事物与关系。mycat子表与父表记录存放在同一个数据分片上,避免跨库join。 |
全局表 | 类似字典表的表 |
2. 环境规划
IP | Port | DB角色 | MyCat |
---|---|---|---|
192.124.64.214 | - | - | MyCat |
192.124.64.212 | 3307 | DB1 master | - |
192.124.64.213 | 3307 | DB2 slave | - |
3.安装布署
3.1 MySQL安装
从库同步:
DB1做为主,DB2,DB3为从库
#授权
grant replication client,replication slave on *.* to 'repl'@'10.%' IDENTIFIED BY 'repl123';
#DB2,DB3建立主从关系
CHANGE MASTER TO
MASTER_HOST='192.124.64.212',
MASTER_PORT=3307,
MASTER_USER='repl',
MASTER_PASSWORD='repl123',
MASTER_AUTO_POSITION = 1;
#
start slave ;
show slave status\G
授权Mycat账号:
grant all privileges on *.* to mycat@'10.%' identified by 'mycat123';
grant all on *.* to 'mycat_r'@'10.%' identified by 'mycat123';
3.2 MyCat软件安装
Mycat 需要先安装Java,然后在 http://www.mycat.org.cn/ 下载软件,解压缩即完成安装。当前版本为 Mycat-server-1.6.7.4。
下载软件
解压软件
配置profile
#安装java 略
#下载软件
$wget 'http://dl.mycat.io/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz' .
#解压,建议路径/usr/local/mycat
$tar -zxvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
$mv mycat /usr/local/
#创建mycat用户
useradd mycat
chown -R mycat:mycat /usr/local/mycat
$vim /etc/profile
#JAVA_HOME=/usr/local/jdk
JAVA_HOME=/usr/java/jdk1.8.0_101
CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME
#M
MYCAT_HOME=/usr/local/mycat
source /etc/profile
MyCat目录介绍:
$tree /usr/local/mycat -L 1
/usr/local/mycat
├── bin # bin 目录里是启动脚本
├── catlet # conf 目录里是配置文件
├── conf # catlet 为 Mycat 的一个扩展功能
├── lib # lib 目录里是 Mycat 和它的依赖 jar
├── logs # logs 目录里是 console.log 用来保存控制台日志,
└── version.txt # 版本
启动/停止:
$su - mycat
$cd /usr/local/mycat/
#启动:
$./mycat start
$./mycat stop
#mycat 支持的命令{ console | start | stop | restart | status | dump }
$bin/mycat
Usage: bin/mycat { console | start | stop | restart | status | dump }
4. MyCAT配置
MyCat是代理,MyCat后面是物理数据库。Mycat 的配置文件都在MYCAT_HOME/conf 目录里面,这里介绍几个常用的文件。若配置文件修改,需要重启 Mycat 或者通过 9066 端口 reload。
文件 | 说明 |
---|---|
server.xml | 定义用户以及系统相关变量,如端口等 |
schema.xml | 定义逻辑库,表、分片节点等内容 |
rule.xml | MyCat 分库分表规则 |
4.1 server.xml
server.xml可用来配置账号,参数及相关操作权限的文件。system标签中设置的是系统级别的相关参数,初始默认即可。user标签是我们要注意的地方。
Mycat 端口是在server.xml中设置。Mycat的默认端口号为:8066 , 管理端口: 9066 有些用户会把Mycat端口8066改为MySQL的3306端口,方便使用。
server.xml
xx 定义MyCAT的账号,用户用此账号访问MyCat。
示例:
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property>
<property name="ignoreUnknownCommand">1</property><!-- 0遇上没有实现的报文(Unknown command:),就会报错、1为忽略该报文,返回ok报文。-->
<property name="defaultSqlParser">druidparser</property>
<property name="serverPort">8066</property>
<property name="managerPort">9066</property>
<property name="idleTimeout">300000</property>
<property name="bindIp">0.0.0.0</property>
</system>
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="defaultSchema">TESTDB</property>
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user_r">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
<property name="defaultSchema">TESTDB</property>
</user>
</mycat:server>
说明:
中的TESTDB,不一定是你数据库上的真实库名。只要和schema.xml中可对应用就。 中定义是Mycat账号,并不是MySQL的账号。
注释掉的privileges 表示mycat用户的操作权限。dml 权限顺序为:insert(新增),update(修改),select(查询),delete(删除),0000–> 1111,0 为禁止权限,1 为开启权限。
4.2 schema.xml
Schema.xml 作为 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库、表、分片规则、DataNode 以 及 DataSource。
schema.xml:
定义逻辑库,逻辑表
定义数据节点,分片
定义数据节点的物理数据库实例、读写分离配置。
示例:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" >
<table name="user" dataNode="dn1"/>
</schema>
<dataNode name="dn1" dataHost="userdb-host1" database="test" />
<dataHost name="userdb-host1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="192.124.64.212" url="192.124.64.212:3307" user="mycat" password="mycat123">
<readHost host="192.124.64.213" url="192.124.64.213:3307" user="mycat" password="mycat123" />
</writeHost>
<writeHost host="192.124.64.213" url="192.124.64.213:3307" user="mycat" password="mycat123"/>
</dataHost>
</mycat:schema>
说明:
schema name='xx'中配置的逻辑库名,dataNode中database是实际的后端DB名。
writeHost标签上的user,password是实际的MySQL账号密码。
若第一个writeHost不可用,mycat将使用第二个writeHost,即实现高可用。
4.3 rule.xml
rule.xml
定义表使用的分片规则。
定义分片算法
示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="rule1">
<rule>
<columns>user_id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
<function name="func1" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">8</property>
<property name="partitionLength">128</property>
</function>
</mycat:rule>
4.4 log4j2.xml
日志配置:
使用 Apache log4j管理日志
配置文件为conf/log4j2.xml
定义日志格式。其中 %d{yyyy-MM-dd HH:mm:ss.SSS} 时间信息; %5p 级别; %t 线程信息 ; %m 提示信息 ; %n回车符。
定义日志级别。
配置日志格式:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] (%l) - %m%n</Pattern>
</PatternLayout>
</Appenders>
<Loggers>
<asyncRoot level="debug" includeLocation="true">
<AppenderRef ref="RollingFile"/>
</asyncRoot>
</Loggers>
</Configuration>
说明:
%d{yyyy-MM-dd HH:mm:ss.SSS} 时间信息; %5p 级别; %t 线程信息 ; %m 提示信息 ; %n回车符
示例:
2020-04-05 22:50:53.122 DEBUG [$_NIOREACTOR-7-RW] (io.mycat.backend.mysql.nio.handler.SingleNodeHandler.execute(SingleNodeHandler.java:186)) - rrs.getRunOnSlave() default
4.5 配置动态加载
登录管理端口,可reload @@config;reload @@config_all;来动态加载配置。
-- 登录管理端口
mysql -h 192.124.64.214 -P 9066 -uroot -p123456 TESTDB
-- 加载schema.xml配置的调整。
reload @@config;
-- 刷新全部配置
reload @@config_all;
5. MyCat管理
通过MyCat管理端口可以方便地进行MyCat管理。
5.1 查看帮助
-- 登录管理端口
mysql -h 192.124.64.214 -P 9066 -uroot -p123456 TESTDB
root@192.124.64.214:9066 : TESTDB > show @@help;
5.2 常用命令
show xx;命令可以show datanode, database,version等等。
reload @@config;
root@192.124.64.214:9066 : TESTDB > show @@version ;
+---------------------------------------------+
| VERSION |
+---------------------------------------------+
| 5.6.29-mycat-1.6.7.4-release-20200105164103 |
+---------------------------------------------+
1 row in set (0.01 sec)
root@192.124.64.214:9066 : TESTDB > show @@server ;
+--------------+-------------+--------------+------------+---------------+---------------+---------+--------+
| UPTIME | USED_MEMORY | TOTAL_MEMORY | MAX_MEMORY | RELOAD_TIME | ROLLBACK_TIME | CHARSET | STATUS |
+--------------+-------------+--------------+------------+---------------+---------------+---------+--------+
| 40m 8s 911ms | 127388176 | 1029177344 | 3817865216 | 1586100586890 | -1 | utf8 | ON |
+--------------+-------------+--------------+------------+---------------+---------------+---------+--------+
1 row in set (0.00 sec)
root@192.124.64.214:9066 : TESTDB > show @@datanode;
+------+-------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| NAME | DATHOST | INDEX | TYPE | ACTIVE | IDLE | SIZE | EXECUTE | TOTAL_TIME | MAX_TIME | MAX_SQL | RECOVERY_TIME |
+------+-------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| dn1 | userdb-host1/test | 0 | mysql | 0 | 8 | 1000 | 269 | 0 | 0 | 0 | -1 |
+------+-------------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
1 row in set (0.00 sec)
root@192.124.64.214:9066 : TESTDB > show @@database ;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.00 sec)
root@192.124.64.214:9066 : TESTDB > show @@datasource;
+----------+---------------+-------+---------------+------+------+--------+------+------+---------+-----------+------------+
| DATANODE | NAME | TYPE | HOST | PORT | W/R | ACTIVE | IDLE | SIZE | EXECUTE | READ_LOAD | WRITE_LOAD |
+----------+---------------+-------+---------------+------+------+--------+------+------+---------+-----------+------------+
| dn1 | 192.124.64.212 | mysql | 192.124.64.212 | 3307 | W | 0 | 8 | 1000 | 275 | 0 | 4 |
| dn1 | 192.124.64.213 | mysql | 192.124.64.213 | 3307 | W | 0 | 1 | 1000 | 262 | 1 | 0 |
| dn1 | 192.124.64.213 | mysql | 192.124.64.213 | 3307 | R | 0 | 8 | 1000 | 272 | 3 | 0 |
+----------+---------------+-------+---------------+------+------+--------+------+------+---------+-----------+------------+
3 rows in set (0.01 sec)
root@192.124.64.214:9066 : TESTDB >show @@sql ;
+------+------+---------------+--------------+-------------------------------------+---------------+
| ID | USER | START_TIME | EXECUTE_TIME | SQL | IP |
+------+------+---------------+--------------+-------------------------------------+---------------+
| 1 | root | 1586098782639 | 2 | select * from user where id=1 | 192.110.91.217 |
| 2 | root | 1586098759715 | 3 | select * from user | 192.110.91.217 |
+------+------+---------------+--------------+-------------------------------------+---------------+
root@192.124.64.214:9066 : TESTDB > show @@backend;
+------------+------+---------+---------------+------+--------+--------+---------+------+--------+----------+------------+--------+---------+---------+------------+
| processor | id | mysqlId | host | port | l_port | net_in | net_out | life | closed | borrowed | SEND_QUEUE | schema | charset | txlevel | autocommit |
+------------+------+---------+---------------+------+--------+--------+---------+------+--------+----------+------------+--------+---------+---------+------------+
| Processor0 | 8 | 1193 | 192.124.64.212 | 3307 | 9440 | 2700 | 662 | 2693 | false | false | 0 | test | utf8:33 | 3 | true |
| Processor0 | 15 | 1132 | 192.124.64.213 | 3307 | 34289 | 2779 | 680 | 2393 | false | false | 0 | test | utf8:33 | 3 | true |
+------------+------+---------+---------------+------+--------+--------+---------+------+--------+----------+------------+--------+---------+---------+------------+
root@192.124.64.214:9066 : TESTDB > reload @@config ;
Query OK, 1 row affected (0.05 sec)
6.读写分离测试
6.1 DB环境准备
建好主从库关系,并建测试表user。Master 192.124.64.212:3307,Slave 192.124.64.213:3307。
# 在Master 192.124.64.212:3307上建表
mysql -h 192.124.64.212 -P 3307 test
SQL>CREATE TABLE user (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(32) DEFAULT NULL,
PRIMARY KEY (id)
)
6.2 配置mycat
读写分离需要配置server.xml,schema.xml,不需要配置rule.xml。
6.2.1 server.xml
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property>
<property name="ignoreUnknownCommand">1</property>
<property name="defaultSqlParser">druidparser</property>
<property name="serverPort">8066</property>
<property name="managerPort">9066</property>
<property name="idleTimeout">300000</property>
<property name="bindIp">0.0.0.0</property>
</system>
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="defaultSchema">TESTDB</property>
<user name="user_r">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
<property name="defaultSchema">TESTDB</property>
</user>
</mycat:server>
6.2.2 schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" >
<table name="user" dataNode="dn1"/>
</schema>
<dataNode name="dn1" dataHost="userdb-host1" database="test" />
<dataHost name="userdb-host1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="192.124.64.212" url="192.124.64.212:3307" user="mycat" password="mycat123">
<readHost host="192.124.64.213" url="192.124.64.213:3307" user="mycat" password="mycat123" />
</writeHost>
</dataHost>
</mycat:schema>
6.2.3 log4j2.xml
修改asyncRoot level="debug"。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Loggers>
<asyncRoot level="debug" includeLocation="true">
<AppenderRef ref="RollingFile"/>
</asyncRoot>
</Loggers>
</Configuration>
6.3 启动MyCat
进入mycat目录,若是单机安装多个mycat可以使用,如下目录。
$cd /data1/mycat_server/mycat-user
$./bin/mycat start
#查看启动日志
$tail logs/mycat.log
$tail logs/wrapper.log
INFO | jvm 1 | 2020/04/05 22:50:36 | MyCAT Server startup successfully. see logs in logs/mycat.log
6.4 测试读写
读写数据:
#登录mycat
mysql -h 192.124.64.214 -P 8066 -uroot -p123456 TESTDB
#写入数据
(192.124.64.214@8066)[TESTDB]>select * from user;
Empty set (0.08 sec)
(192.124.64.214@8066)[TESTDB]>insert into user values(1,'zhang3');
Query OK, 1 row affected (0.02 sec)
(192.124.64.214@8066)[TESTDB]>insert into user values(2,'li4');
Query OK, 1 row affected (0.01 sec)
(192.124.64.214@8066)[TESTDB]>select * from user;
+----+--------+
| id | name |
+----+--------+
| 1 | zhang3 |
| 2 | li4 |
+----+--------+
2 rows in set (0.01 sec)
查看日志:
$tail -f logs/mycat.log
## write
2020-04-05 22:51:08.099 DEBUG [$_NIOREACTOR-7-RW] (io.mycat.server.NonBlockingSession.execute(NonBlockingSession.java:126)) - ServerConnection [id=1, schema=TESTDB, host=192.110.91.217, user=root,txIsolation=3, autocommit=true, schema=TESTDB, executeSql=insert into user values(1,'zhang3')]insert into user values(1,'zhang3'), route={
1 -> dn1{insert into user values(1,'zhang3')}
} rrs
...
2020-04-05 22:51:08.105 DEBUG [$_NIOREACTOR-1-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:386)) - release connection MySQLConnection@720534076 [id=1, lastTime=1586098268090, user=mycat, schema=test, old shema=test, borrowed=true, fromSlaveDB=false, threadId=1194, charset=utf8, txIsolation=3, autocommit=true, attachment=dn1{insert into user values(1,'zhang3')}, respHandler=SingleNodeHandler [node=dn1{insert into user values(1,'zhang3')}, packetId=1], host=192.124.64.212, port=3307, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
## read
2020-04-05 22:50:53.124 DEBUG [$_NIOREACTOR-7-RW] (io.mycat.backend.datasource.PhysicalDBNode.getConnection(PhysicalDBNode.java:133)) - rrs.getRunOnSlave() default
2020-04-05 22:50:53.124 DEBUG [$_NIOREACTOR-7-RW] (io.mycat.backend.datasource.PhysicalDBPool.getRWBanlanceCon(PhysicalDBPool.java:556)) - select read source 192.124.64.213 for dataHost:userdb-host1
2020-04-05 22:50:53.126 DEBUG [$_NIOREACTOR-5-RW] (io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:386)) - release connection MySQLConnection@1477164757 [id=13, lastTime=1586098253110, user=mycat, schema=test, old shema=test, borrowed=true, fromSlaveDB=true, threadId=1130, charset=utf8, txIsolation=3, autocommit=true, attachment=dn1{SELECT *
FROM user
LIMIT 100}, respHandler=SingleNodeHandler [node=dn1{SELECT *
FROM user
LIMIT 100}, packetId=4], host=192.124.64.213, port=3307, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
说明 :
写时日志:node=dn1{insert into user values(1,'zhang3')}, packetId=1], host=192.124.64.212, port=3307。
读时日志: select read source 192.124.64.213 for dataHost:userdb-host1。
根据日志说明,mycat确实进行了正确的读写分离。
6. 单库分表测试
MyCat较多示例使用的是分库sharding。MyCat1.6版本以后,也可支持单库分表,配置参数为。
6.1 DB环境准备
数据库继续使用上节的192.124.64.212:3307 。分表测试以电商常见的购物车为例,假定购物车分表为shoppingcart0~shoppingcart99。
创建模板表:
-- 在主库上创建shoppingcart库
mysql -h 192.124.64.212 -P 3307 -u mycat -pmycat123
create database shoppingcart;
-- cart_id 其实常由发号器生成,全局唯一。cart_id是shopping_cart_items外键。
create table shopping_cart_0 (
cart_id int(11) NOT NULL AUTO_INCREMENT,
user_id int(10) unsigned not null,
create_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`cart_id`)
)
创建分表:使用shell的for循环来创建分表。
for ((i=0;i<=99;i++)) ; do echo "create table shopping_cart_$i like shopping_cart_0"| mysql -h 192.124.64.212 -P 3307 shoppingcart ; done;
6.2 MyCat配置
6.2.1 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="nonePasswordLogin">0</property>
<property name="ignoreUnknownCommand">1</property>
<property name="defaultSqlParser">druidparser</property>
<property name="serverPort">8066</property>
<property name="managerPort">9066</property>
<property name="idleTimeout">300000</property>
<property name="bindIp">0.0.0.0</property>
<property name="processors">128</property>
<property name="processorExecutor">32</property>
</system>
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="defaultSchema">TESTDB</property>
</user>
<user name="user_r">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
<property name="defaultSchema">TESTDB</property>
</user>
</mycat:server>
6.2.2 schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" >
<table name="shoppingcart" primaryKey="cart_id" dataNode="dn_cart_0" subTables="shopping_cart_$0-99" rule="modByUserId"/>
</schema>
<dataNode name="dn_cart_0" dataHost="cartdb-host1" database="shoppingcart" />
<dataHost name="cartdb-host1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="cartM1" url="192.124.64.212:3307" user="mycat" password="mycat123">
<readHost host="cartS1" url="192.124.64.213:3307" user="mycat" password="mycat123" />
</writeHost>
</dataHost>
</mycat:schema>
注意配置中subTables="shoppingcart$0-99" 及rule="modByUserId"。
6.2.3 rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="modByUserId">
<rule>
<columns>user_id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes ,依子表的数量-->
<property name="count">100</property>
</function>
</mycat:rule>
rule配置分片规则,count中配置为子表的数量,本例中为100。
6.3 启动MyCat
$./bin/mycat start
#查看启动日志
$tail logs/mycat.log
6.4 测试分表读写
MyCat写入数据:在mycat中插入几条数据
mysql -h 192.124.64.214 -P 8066 -uroot -p123456 TESTDB -A
(192.124.64.214@8066)[TESTDB]>select * from shoppingcart;
Empty set (0.40 sec)
(192.124.64.214@8066)[TESTDB]>show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| shoppingcart |
+------------------+
1 row in set (0.01 sec)
(192.124.64.214@8066)[TESTDB]>insert into shoppingcart(cart_id,user_id) values(1,101);
Query OK, 1 row affected (0.02 sec)
(192.124.64.214@8066)[TESTDB]>insert into shoppingcart(cart_id,user_id) values(2,102);
Query OK, 1 row affected (0.01 sec)
(192.124.64.214@8066)[TESTDB]>select * from shoppingcart ;
+---------+---------+---------------------+
| cart_id | user_id | create_at |
+---------+---------+---------------------+
| 1 | 101 | 2020-04-06 23:43:50 |
| 2 | 102 | 2020-04-06 23:43:57 |
+---------+---------+---------------------+
2 rows in set (0.07 sec)
后端MySQL检查:
mysql -h 192.124.64.212 -P 3307 shoppingcart -u mycat -pmycat123
mycat@192.124.64.212:3307 : shoppingcart > select * from shopping_cart_1;
+---------+---------+---------------------+
| cart_id | user_id | create_at |
+---------+---------+---------------------+
| 1 | 101 | 2020-04-06 23:43:50 |
+---------+---------+---------------------+
1 row in set (0.00 sec)
mycat@192.124.64.212:3307 : shoppingcart > select * from shopping_cart_2;
+---------+---------+---------------------+
| cart_id | user_id | create_at |
+---------+---------+---------------------+
| 2 | 102 | 2020-04-06 23:43:57 |
+---------+---------+---------------------+
1 row in set (0.00 sec)
mycat@192.124.64.212:3307 : shoppingcart > select * from shopping_cart_3;
Empty set (0.00 sec)
参考:
官方 http://www.mycat.org.cn/
指南 http://www.mycat.io/document/mycat-definitive-guide.pdf
Mycat水平拆分之十种分片规则
http://www.imooc.com/learn/951
https://www.jianshu.com/p/fc11d28c67dc