MySQL分库分表可以通过中间件Mycat实现,本文简要介绍了Mycat的几种分片策略mode、range和hash,并分别进行测试验证
1、MySQL基于Mycat实现分库分表
1.1 分库分表原理
数据的切分(sharding)根据切分规则的类型,可以分为垂直切分和水平切分两种模式:
- 垂直切分是按照不同的表切分到不同的数据库中,适用于业务系统之间耦合度低、业务逻辑清晰的系统
- 水平切分是根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库上,对应用来说更为复杂
分库分表根据垂直和水平切分分为四种:水平分库、水平分表、垂直分库、垂直分表。
- MySQL垂直分区
MySQL垂直分区是在应用层将不同业务的数据放到不同的数据库服务器,当其中一个业务崩溃了也不会影响其他业务的正常进行,并且可以起到负载分流的作用,大大提升了数据库的吞吐能力。经过垂直分区后的数据库架构图如下:
垂直分区是通过不同业务进行分库,但是有些业务之间或多或少总会有点联系,而且这种分区不能解决单个业务数据量暴涨的问题。
- MySQL水平分片(Sharding)
MySQL水平分片是将业务数据按照一定规则(如id哈希)分组,并把该组的数据存储到一个数据库分片中,这样随着用户数量的增加,只要简单地配置一台服务器即可,原理图如下:
分表分库虽然能解决大表对数据库系统的压力,但它并不是万能的,分库分表有以下原则:
- 1000 万以内的表,不建议分片,通过合适的索引,可以解决性能问题
- 分片数量尽量少,尽量均匀分布在多个 主机上,因为一个查询SQL跨分片越多,则总体性能越差
- 分片规则的选择,需要考虑数据的增长模式,数据的访问模式,分片关联性问题,以及分片扩容问题
- 尽量不要在一个事务中的 SQL 跨越多个分片
- 查询条件尽量优化,尽量避免“Select *”的方式,大量数据结果集下,会消耗大量带宽和 CPU 资源
1.2 Mycat实现分库分表
MyCAT通过定义表的分片规则来实现分片,分片规则中会定义分片字段和分片算法,分片算法包括hash、取模和范围分区等。每个表可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法 。
- Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
- Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。
- DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上
- Database:定义某个物理库的访问地址,用于捆绑到Datanode上
- 分片规则:前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度
1.2.1 环境准备
1)MySQL主从复制集群环境:参考“MySQL主从复制集群架构部署”
2)Mycat安装:参考“MySQL主从复制读写分离实现”
3)启动MySQL集群环境
[mysql@tango-centos01 mysql]$ service mysql start
[mysql@tango-centos01 mysql]$ service mysql status
1.2.2 MyCAT分库分表配置
Mycat中配置文件主要有schema.xml和rule.xml:schema.xml指定的是各个数据库节点与MyCat中虚拟数据库和表的关联关系,并且指定了当前表的分表策略;在rule.xml中则指定了具体的分表策略及其所使用的算法实现类。MyCAT中常用分片算法包括取模、范围分片和一致性hash算法,以下分别介绍三种算法配置。
1)取模
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 指定了对外所展示的数据库名称,也就是说,客户端连接MyCat数据库时,制定的database为mydb
而当前数据库中的表的配置就是根据下面的配置而来的 -->
<schema name="mydb" checkSQLschema="true" sqlMaxLimit="100">
<!-- 定义了一个t_goods表,该表的主键是id,该字段是自增长的,并且该表的数据会被分配到dn1,dn2和
dn3上,这三个指的是当前MyCat数据库所代理的真实数据库的节点名,每个节点的具体配置在下面的
配置中。这里rule属性指定了t_goods表中的数据分配到dn1,dn2和dn3上的策略,mod-long指的是
按照长整型取余的方式分配,也就是按照id对节点数目进行取余 -->
<table name="t_goods" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3"
rule="mod-long"/>
</schema>
<!-- 分别指定了dn1,dn2和dn3三个节点与对应的数据库的关系,dataHost对应的就是下面的数据库节点配置 -->
<dataNode name="dn1" dataHost="dhost1" database="db1"/>
<dataNode name="dn2" dataHost="dhost2" database="db2"/>
<dataNode name="dn3" dataHost="dhost3" database="db3"/>
<!-- 这里分别指定了各个数据库节点的配置 -->
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0"
dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="localhost:3306" user="root" password="password"/>
</dataHost>
a
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0"
dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM2" url="localhost:3306" user="root" password="password"/>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0"
dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM3" url="localhost:3306" user="root" password="password"/>
</dataHost>
</mycat:schema>
rules.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<!-- 这里的mod-long对应的就是上面schema.xml的表配置中rule属性所使用的规则名称,其columns节点
指定了当前规则所对应的字段名,也就是id,algorithm节点则指定了当前规则所使用的算法,具体的
算法对应于下面的function节点所指定的实现类-->
<tableRule name="mod-long">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<!-- 这里指定的是mod-long这个算法所使用的具体实现类,实现类需要使用全限定路径,具体的代码读者朋友
可以阅读MyCat源码,并且读者也可以查看MyCat默认为我们提供了哪些分表策略实现 -->
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- 指定了当前所使用的数据库节点数 -->
<property name="count">3</property>
</function>
</mycat:rule>
2)按范围分片
按照范围分片,顾名思义,就是首先对整体数据进行范围划分,然后将各个范围区间分配到对应的数据库节点上,当用户插入数据时,根据指定字段的值,判断其属于哪个范围,然后将数据插入到该范围对应的数据库节点上。
<!-- schema.xml -->
<table name="t_company" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="range-sharding-by-id-count"/>
rules.xml配置如下:
<!-- rule.xml -->
<tableRule name="range-sharding-by-id-count">
<rule>
<!-- 指定了分片字段 -->
<columns>id</columns>
<algorithm>range-id-count</algorithm>
</rule>
</tableRule>
<function name="range-id-count" class="io.mycat.route.function.AutoPartitionByLong">
<!-- 指定了范围分片的”范围-节点“的对应策略 -->
<property name="mapFile">files/tb-range-partition.txt</property>
<!-- 指定了超出范围的数据将会被分配的数据节点 -->
<property name="defaultNode">0</property>
</function>
其中mapFile指定范围和数据节点的对应关系,如下:
<!-- 上面mapFile属性指定的id-range-partition.txt文件内容,这里指定了具体的范围与数据节点的对应关系 -->
0-10=0
11-50=1
51-100=2
101-1000=0
1001-9999=1
10000-9999999=2
3)一致性Hash分片
<!-- schema.xml -->
<table name="t_house" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="sharding-by-hash"/>
rule.xml文件如下:
<!-- rule.xml -->
<tableRule name="sharding-by-murmur">
<rule>
<columns>id</columns>
<algorithm>hash</algorithm>
</rule>
</tableRule>
<!-- 下面的属性中,count指定了要分片的数据库节点数量,必须指定,否则没法分片;virtualBucketTimes指的是
一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍;
weightMapFile指定了节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,
以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,
否则以1代替;bucketMapPath用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,
会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,
就不会输出任何东西-->
<function name="hash" class="io.mycat.route.function.PartitionByMurmurHash">
<property name="seed">0</property><!-- 默认是0 -->
<property name="count">3</property>
<property name="virtualBucketTimes">160</property><!-- -->
<!-- <property name="weightMapFile">weightMapFile</property> -->
<property name="bucketMapPath">
/usr/local/mycat/bucketMap.txt</property>
</function>
1.2.3 MyCAT分库分表测试
MyCat分库分表测试场景如下:
1)创建数据库和表
在主机192.168.112.101的mysql上创建数据库TESTDB01和TESTDB02,在192.168.112.102和192.168.112.103上分别创建数据库TESTDB03和TESTDB04。需要将表TB01放在库TESTDB01和TESTDB02中,表TB02分表放到库TESTDB02、TESTDB03和TESTDB04中,表TB03放到TESTDB03和TESTDB04中。
- 在192.168.112.101节点
[mysql@tango-centos01 mysql]$ ./bin/mysql -uroot –ppassword
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.31-log MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE TESTDB01 CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.89 sec)
mysql> use TESTDB01;
Database changed
mysql> create table TB01 (id int not null auto_increment,city varchar(50) not null, primary key(id)) AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.36 sec)
mysql> CREATE DATABASE TESTDB02 CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
mysql> use TESTDB02;
Database changed
mysql> create table TB01 (id int not null auto_increment,city varchar(50) not null, primary key(id)) AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.22 sec)
mysql> create table TB02 (id int not null auto_increment,city varchar(50) not null, primary key(id)) AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)
- 在192.168.112.102节点
[mysql@tango-centos02 mysql]$ ./bin/mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 41
Server version: 5.7.31-log MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE TESTDB03 CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.11 sec)
mysql> use TESTDB03;
Database changed
mysql> create table TB02 (id int not null auto_increment,city varchar(50) not null, primary key(id)) AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.29 sec)
mysql> create table TB03 (id int not null auto_increment,city varchar(50) not null, primary key(id)) AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)
- 在192.168.112.103节点
[mysql@tango-centos03 mysql]$ ./bin/mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 47
Server version: 5.7.31-log MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE TESTDB04 CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.11 sec)
mysql> use TESTDB04;
Database changed
mysql> create table TB02 (id int not null auto_increment,city varchar(50) not null, primary key(id)) AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.05 sec)
mysql> create table TB03 (id int not null auto_increment,city varchar(50) not null, primary key(id)) AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)
特别需要注意的是:
- 分表的表在创建时一定要创建主键,否则在mycat端写入数据时会报错主键冲突
- 分表的表要在跨库的几个库上都要创建。
2)配置MyCAT
登录mycat机器192.168.112.10机器,分别设置server.xml文件、rule.xml文件、schema.xml文件
- server.xml配置
[root@tango-01 mycat]## vim conf/server.xml
......
<!-- mycat的服务端口默认为8066,管理端口默认为9066 -->
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
.....
<!-- 任意设置登陆 mycat 的用户名,密码,数据库 -->
<user name="root">
<property name="password">password</property>
<property name="schemas">mycat</property>
.....
</mycat:server>
- 配置Rules文件
分库分表配置涉及到rule.xml文件,本次测试过程中分别验证取模、范围和一致性hash三种分片算法,配置如下:
[root@tango-01 conf]# cp rule.xml rule.xml.bak
[root@tango-01 conf]# vim rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="mod-rule"> <!—TB01表分片的规则名,这里定义为取模分区mod-rule,这个需要在schema.xml文件中引用 -->
<rule>
<columns>id</columns> <!—TB01表的分片列 -->
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<tableRule name="range-rule"> <!—TB02表分片的规则名,这里定义为范围分区range-rule,这个需要在schema.xml文件中引用 -->
<rule>
<columns>id</columns> <!—TB02表的分片列 -->
<algorithm>range-id-count</algorithm>
</rule>
</tableRule>
<tableRule name="hash-rule"> <!—TB03表分片的规则名,这里定义为范围分区range-rule,这个需要在schema.xml文件中引用 -->
<rule>
<columns>id</columns> <!—TB02表的分片列 -->
<algorithm>hash-murmur</algorithm>
</rule>
</tableRule>
<!—TB01表分配到TESTDB01和TESTDB02库中 -->
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">2</property> <!-- count值与分片个数相同,这里TB01表分片到TESTDB01库和TESTDB02库里,共2份。 -->
</function>
<!—TB02表分配到TESTDB02、TESTDB03和TESTDB04库中 -->
<function name="range-id-count" class="io.mycat.route.function.AutoPartitionByLong">
<!-- 指定了范围分片的”范围-节点“的对应策略 -->
<property name="mapFile">files/tb02-range-partition.txt</property>
<!-- 指定了超出范围的数据将会被分配的数据节点 -->
<property name="defaultNode">0</property>
</function>
<!—TB03表分配到TESTDB03和TESTDB04库中 -->
<function name="hash-murmur" class="io.mycat.route.function.PartitionByMurmurHash">
<property name="seed">0</property><!-- 默认是0 -->
<property name="count">2</property>
<property name="virtualBucketTimes">160</property><!-- -->
<property name="bucketMapPath">/usr/local/mycat/tb03-bucketMap.txt</property>
</function>
</mycat:rule>
创建文件files/tb02-range-partition.txt
0-10=0
11-50=1
51-100=2
101-1000=0
1001-9999=1
10000-9999999=2
- 配置schema.xml文件
[root@tango-01 conf]# cp schema.xml schema.xml.old
[root@tango-01 conf]# vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycat" checkSQLschema="false" sqlMaxLimit="100">
<table name="TB01" primaryKey="id" dataNode=" DN01,DN02" rule="mod-rule" />
<table name="TB02" primaryKey="id" dataNode=" DN02,DN03,DN04" rule="range-rule" />
<table name="TB03" primaryKey="id" dataNode="DN03,DN04" rule="hash-rule" />
</schema>
<dataNode name="DN01" dataHost="DH01" database=" TESTDB01" />
<dataNode name="DN02" dataHost="DH01" database=" TESTDB02" />
<dataNode name="DN03" dataHost="DH02" database=" TESTDB03" />
<dataNode name="DN04" dataHost="DH03" database=" TESTDB04" />
<dataHost name="DH01" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.112.101" url="192.168.112.101:3306" user="root" password="password">
</writeHost>
</dataHost>
<dataHost name="DH02" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" >
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.112.102" url="192.168.112.102:3306" user="root" password="password">
</writeHost>
</dataHost>
<dataHost name="DH03" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.112.103" url="192.168.112.103:3306" user="root" password="password">
</writeHost>
</dataHost>
</mycat:schema>
4)启动Mycat服务
[root@tango-01 mycat]# ./bin/mycat start
Starting Mycat-server...
[root@tango-01 mycat]# ./bin/mycat status
Mycat-server is running (9348).
[root@tango-01 mycat]# lsof -i:8066
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 9350 root 81u IPv6 215883 0t0 TCP *:8066 (LISTEN)
[root@tango-01 mycat]# lsof -i:9066
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 9350 root 77u IPv6 215878 0t0 TCP *:9066 (LISTEN)
5)在客户机远程登录Mycat
[root@tango-01 mysql]# ./bin/mysql -h192.168.112.10 -P8066 -uroot -ppassword
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.29-mycat-1.6.7.1-release-20200209222254 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> show databases;
+----------+
| DATABASE |
+----------+
| mycat |
+----------+
1 row in set (0.00 sec)
mysql> use mycat
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables in mycat |
+-----------------+
| tb01 |
| tb02 |
| tb03 |
+-----------------+
3 rows in set (0.00 sec)
mysql> select * from TB01;
Empty set (0.14 sec)
mysql> select * from TB02;
Empty set (0.58 sec)
mysql> select * from TB03;
Empty set (0.04 sec)
6)验证Mod分片策略
- 在mycat里往TB01
mysql> insert into TB01(id,city) values(1,"Anhui");
Query OK, 1 row affected (0.06 sec)
mysql> insert into TB01(id,city) values(2,"Beijing");
Query OK, 1 row affected (0.00 sec)
mysql> insert into TB01(id,city) values(11,"Guangzhou");
Query OK, 1 row affected (0.00 sec)
mysql> insert into TB01(id,city) values(21,"Shenzhen");
Query OK, 1 row affected (0.01 sec)
特别注意:在配置了sharding分片策略之后(如heihei表),mycat里分片的表做插入数据时,即使插入所有字段的数据,也一定要在表名后面写明插入数据的字段名称,否则插入数据会报错:ERROR 1064 (HY000): partition table, insert must provide ColumnList
- 登录192.168.112.101服务器,查看从mycat端写入的数据
mysql> use TESTDB01;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+--------------------+
| Tables_in_TESTDB01 |
+--------------------+
| TB01 |
+--------------------+
1 row in set (0.00 sec)
mysql> select * from TB01;
+----+---------+
| id | city |
+----+---------+
| 2 | Beijing |
+----+---------+
1 row in set (0.03 sec)
mysql> use TESTDB02;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+--------------------+
| Tables_in_TESTDB02 |
+--------------------+
| TB01 |
| TB02 |
+--------------------+
2 rows in set (0.00 sec)
mysql> select * from TB01;
+----+-----------+
| id | city |
+----+-----------+
| 1 | Anhui |
| 11 | Guangzhou |
| 21 | Shenzhen |
+----+-----------+
3 rows in set (0.00 sec)
7)验证范围分片策略
- 在mycat里往TB02插入数据
mysql> insert into TB02(id,city) values(1,"Anhui");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB02(id,city) values(2,"Beijing");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB02(id,city) values(11,"Guangzhou");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB02(id,city) values(21,"Shenzhen");
Query OK, 1 row affected (0.02 sec)
mysql> insert into TB02(id,city) values(61,"Chengdu");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB02(id,city) values(132,"Hangzhou");
Query OK, 1 row affected (0.00 sec)
mysql> select * from TB02;
+-----+-----------+
| id | city |
+-----+-----------+
| 1 | Anhui |
| 2 | Beijing |
| 132 | Hangzhou |
| 11 | Guangzhou |
| 21 | Shenzhen |
| 61 | Chengdu |
+-----+-----------+
6 rows in set (0.02 sec)
- 登录192.168.112.101-103服务器,查看从mycat端写入的数据
mysql> use TESTDB02;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+--------------------+
| Tables_in_TESTDB02 |
+--------------------+
| TB01 |
| TB02 |
+--------------------+
2 rows in set (0.00 sec)
mysql> select * from TB02;
+-----+----------+
| id | city |
+-----+----------+
| 1 | Anhui |
| 2 | Beijing |
| 132 | Hangzhou |
+-----+----------+
3 rows in set (0.00 sec)
mysql> use TESTDB03;
Database changed
mysql> show tables;
+--------------------+
| Tables_in_TESTDB03 |
+--------------------+
| TB02 |
| TB03 |
+--------------------+
2 rows in set (0.00 sec)
mysql> select * from TB02;
+----+-----------+
| id | city |
+----+-----------+
| 11 | Guangzhou |
| 21 | Shenzhen |
+----+-----------+
2 rows in set (0.00 sec)
mysql> use TESTDB04;
Database changed
mysql> show tables;
+--------------------+
| Tables_in_TESTDB04 |
+--------------------+
| TB02 |
| TB03 |
+--------------------+
2 rows in set (0.00 sec)
mysql> select * from TB02;
+----+---------+
| id | city |
+----+---------+
| 61 | Chengdu |
+----+---------+
1 row in set (0.00 sec)
8)验证Hash分片策略
- 在mycat里往TB03插入数据
mysql> insert into TB03(id,city) values(1,"Anhui");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB03(id,city) values(2,"Beijing");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB03(id,city) values(11,"Guangzhou");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB03(id,city) values(21,"Shenzhen");
Query OK, 1 row affected (0.02 sec)
mysql> insert into TB03(id,city) values(61,"Chengdu");
Query OK, 1 row affected (0.01 sec)
mysql> insert into TB03(id,city) values(132,"Hangzhou");
Query OK, 1 row affected (0.00 sec)
mysql> select * from TB03;
+-----+-----------+
| id | city |
+-----+-----------+
| 1 | Anhui |
| 2 | Beijing |
| 132 | Hangzhou |
| 11 | Guangzhou |
| 21 | Shenzhen |
| 61 | Chengdu |
+-----+-----------+
6 rows in set (0.02 sec)
- 登录192.168.112.102-103服务器,查看从mycat端写入的数据
mysql> select * from TESTDB03.TB03;
+----+----------+
| id | city |
+----+----------+
| 21 | Shenzhen |
+----+----------+
1 row in set (0.00 sec)
mysql> select * from TESTDB04.TB03;
+-----+-----------+
| id | city |
+-----+-----------+
| 1 | Anhui |
| 2 | Beijing |
| 11 | Guangzhou |
| 61 | Chengdu |
| 132 | Hangzhou |
+-----+-----------+
5 rows in set (0.00 sec)
从上面可以看出,TB01、TB02和TB03使用mycat中的mod、range和hash三种分片策略,成功实现了分库分表功能。
参考资料
- http://mycat.org.cn/document/mycat-definitive-guide.pdf
- https://www.cnblogs.com/kevingrace/p/9365840.html
- https://www.cnblogs.com/littlecharacter/p/9342129.html
- https://www.jianshu.com/p/c6e29d724fca
- https://my.oschina.net/ydsakyclguozi/blog/199498
- https://my.oschina.net/zhangxufeng/blog/3097533
转载请注明原文地址:https://blog.csdn.net/solihawk/article/details/117837927
文章会同步在公众号“牧羊人的方向”更新,感兴趣的可以关注公众号,谢谢!