Mysql之Mycat读写分离及分库分表

## 什么是mycat
```basic  
1、一个彻底开源的,面向企业应用开发的大数据库集群  
2、支持事务、ACID、可以替代MySQL的加强版数据库  
3、一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群  
4、一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server  
5、结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品  
6、一个新颖的数据库中间件产品  
```  
 
 
 
## Mycat原理  
 
 
 
 
然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。  
如下图:  
 
因此你可以用一台到N台服务器来分片,分片规则为(sharding rule)典型的字符串枚举分片规则,一个规则的定义是分片字段(sharding column)+分片函数(rule function),  
 
 
 
然后将SQL发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端。以select * from Orders where prov=?语句为例,查到prov=wuhan,按照分片函数,wuhan返回dn1,  
于是SQL就发给了MySQL1,去取DB1上的查询结果,并返回给用户。  
 
如果上述SQL改为select * from Orders where prov in (‘wuhan’,‘beijing’),那么,SQL就会发给MySQL1与MySQL2去执行,然后结果集合并后输出给用户。但通常业务中我们的SQL会有Order By  
以及Limit翻页语法,此时就涉及到结果集在Mycat端的二次处理,这部分的代码也比较复杂,而最复杂的则属两个表的Jion问题,  
 
为此,Mycat提出了创新性的ER分片、全局表、HBT(Human Brain Tech)人工智能的Catlet、以及结合Storm/Spark引擎等十八般武艺的解决办法,从而成为目前业界最强大的方案,这就是开源的力量!  
 
1.png  
 
## 为什么使用Mycat  
 
如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求;  
 
 
 
一些折衷是无法满足使用场景的,就比如有些使用场景是绝对要有事务与安全指标的。这个时候NoSQL肯定是无法满足的,所以还是需要使用关系性数据库。  
 
如何使用关系型数据库解决海量存储的问题呢?此时就需要做数据库集群,为了提高查询性能将一个数据库的数据分散到不同的数据库中存储,为应对此问题就出现了——MyCat  
 
核心技术(分库分表)  
 
数据库分片指:通过某种特定的条件,将我们存放在一个数据库中的数据分散存放在不同的多个数据库(主机)中,这样来达到分散单台设备的负载,根据切片规则,可分为以下两种切片模式  
MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法  
 
1 . Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。  
2 . Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。  
3 . DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上  
4.DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上  
5 . 分片规则:前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难  
 
## Mycat读写分离  
 
· 基础架构图  
 
 
 
2.png  
 
### 环境准备  
 
 
 
 
 
 
 
 
 
 
 
 
### 二进制安装mysql  
 
1.创建目录初始化数据  
 
```bash  
mkdir /data/33{07..10}/data -p  
mysqld --initialize-insecure --user=mysql --datadir=http://www.likecs.com/data/3307/data --basedir=http://www.likecs.com/app/mysql  
mysqld --initialize-insecure --user=mysql --datadir=http://www.likecs.com/data/3308/data --basedir=http://www.likecs.com/app/mysql  
mysqld --initialize-insecure --user=mysql --datadir=http://www.likecs.com/data/3309/data --basedir=http://www.likecs.com/app/mysql  
mysqld --initialize-insecure --user=mysql --datadir=http://www.likecs.com/data/3310/data --basedir=http://www.likecs.com/app/mysql  
```  
 
 
2.准备配置文件和启动脚本  
 
```bash  
db01======  
cat >/data/3307/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3307/data  
socket=http://www.likecs.com/data/3307/mysql.sock  
port=3307  
log-error=http://www.likecs.com/data/3307/mysql.log  
log_bin=http://www.likecs.com/data/3307/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=7  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
 
cat >/data/3308/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3308/data  
port=3308  
socket=http://www.likecs.com/data/3308/mysql.sock  
log-error=http://www.likecs.com/data/3308/mysql.log  
log_bin=http://www.likecs.com/data/3308/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=8  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
 
cat >/data/3309/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3309/data  
socket=http://www.likecs.com/data/3309/mysql.sock  
port=3309  
log-error=http://www.likecs.com/data/3309/mysql.log  
log_bin=http://www.likecs.com/data/3309/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=9  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
cat >/data/3310/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3310/data  
socket=http://www.likecs.com/data/3310/mysql.sock  
port=3310  
log-error=http://www.likecs.com/data/3310/mysql.log  
log_bin=http://www.likecs.com/data/3310/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=10  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
 
cat >/etc/systemd/system/mysqld3307.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3307/my.cnf  
LimitNOFILE = 5000  
EOF  
 
cat >/etc/systemd/system/mysqld3308.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3308/my.cnf  
LimitNOFILE = 5000  
EOF  
 
cat >/etc/systemd/system/mysqld3309.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3309/my.cnf  
LimitNOFILE = 5000  
EOF  
cat >/etc/systemd/system/mysqld3310.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
 
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3310/my.cnf  
LimitNOFILE = 5000  
EOF  
db02=======  
cat >/data/3307/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3307/data  
socket=http://www.likecs.com/data/3307/mysql.sock  
port=3307  
log-error=http://www.likecs.com/data/3307/mysql.log  
log_bin=http://www.likecs.com/data/3307/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=17  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
cat >/data/3308/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3308/data  
port=3308  
socket=http://www.likecs.com/data/3308/mysql.sock  
log-error=http://www.likecs.com/data/3308/mysql.log  
log_bin=http://www.likecs.com/data/3308/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=18  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
cat >/data/3309/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3309/data  
socket=http://www.likecs.com/data/3309/mysql.sock  
port=3309  
log-error=http://www.likecs.com/data/3309/mysql.log  
log_bin=http://www.likecs.com/data/3309/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=19  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
 
 
cat >/data/3310/my.cnf<<EOF  
[mysqld]  
basedir=http://www.likecs.com/app/mysql  
datadir=http://www.likecs.com/data/3310/data  
socket=http://www.likecs.com/data/3310/mysql.sock  
port=3310  
log-error=http://www.likecs.com/data/3310/mysql.log  
log_bin=http://www.likecs.com/data/3310/mysql-bin  
binlog_format=row  
skip-name-resolve  
server-id=20  
gtid-mode=on  
enforce-gtid-consistency=true  
log-slave-updates=1  
EOF  
 
cat >/etc/systemd/system/mysqld3307.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3307/my.cnf  
LimitNOFILE = 5000  
EOF  
 
cat >/etc/systemd/system/mysqld3308.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3308/my.cnf  
LimitNOFILE = 5000  
EOF  
 
cat >/etc/systemd/system/mysqld3309.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3309/my.cnf  
LimitNOFILE = 5000  
EOF  
cat >/etc/systemd/system/mysqld3310.service<<EOF  
[Unit]  
Description=MySQL Server  
Documentation=man:mysqld(8)  
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html  
After=network.target  
After=syslog.target  
[Install]  
WantedBy=multi-user.target  
[Service]  
User=mysql  
Group=mysql  
ExecStart=http://www.likecs.com/app/mysql/bin/mysqld --defaults-file=http://www.likecs.com/data/3310/my.cnf  
LimitNOFILE = 5000  
EOF  
```  
 
 
3.修改权限启动多实例  
 
```bash  
chown -R mysql.mysql /data/*  
systemctl start mysqld3307  
systemctl start mysqld3308  
systemctl start mysqld3309  
systemctl start mysqld3310  
 
mysql -S /data/3307/mysql.sock -e "show variables like 'server_id'"  
mysql -S /data/3308/mysql.sock -e "show variables like 'server_id'"  
mysql -S /data/3309/mysql.sock -e "show variables like 'server_id'"  
mysql -S /data/3310/mysql.sock -e "show variables like 'server_id'"  
```  
 
 
4.主从配置  
 
```bash  
箭头指向谁是主库  
10.0.0.51:3307 <-----> 10.0.0.52:3307  
10.0.0.51:3309 ------> 10.0.0.51:3307  
10.0.0.52:3309 ------> 10.0.0.52:3307  
 
10.0.0.52:3308 <-----> 10.0.0.51:3308  
10.0.0.52:3310 -----> 10.0.0.52:3308  
10.0.0.51:3310 -----> 10.0.0.51:3308  
```  
 
 
5.分片规划  
 
```bash  
shard1:  
Master:10.0.0.51:3307  
slave1:10.0.0.51:3309  
Standby Master:10.0.0.52:3307  
slave2:10.0.0.52:3309  
shard2:  
Master:10.0.0.52:3308  
slave1:10.0.0.52:3310  
Standby Master:10.0.0.51:3308  
slave2:10.0.0.51:3310  
```  
 
 
6.配置操作  
 
```bash  
# db02  
mysql -S /data/3307/mysql.sock -e "grant replication slave on . to repl@'10.0.0.%' identified by '123';"  
mysql -S /data/3307/mysql.sock -e "grant all on . to root@'10.0.0.%' identified by '123' with grant option;"  
 
# db01  
mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3307/mysql.sock -e "start slave;"  
mysql -S /data/3307/mysql.sock -e "show slave status\G"  
 
 
# db02  
mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3307/mysql.sock -e "start slave;"  
mysql -S /data/3307/mysql.sock -e "show slave status\G"  
 
# db01  
mysql -S /data/3309/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3309/mysql.sock -e "start slave;"  
mysql -S /data/3309/mysql.sock -e "show slave status\G"  
 
# db02  
mysql -S /data/3309/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3309/mysql.sock -e "start slave;"  
mysql -S /data/3309/mysql.sock -e "show slave status\G"  
 
# db01  
mysql -S /data/3308/mysql.sock -e "grant replication slave on . to repl@'10.0.0.%' identified by '123';"  
mysql -S /data/3308/mysql.sock -e "grant all on . to root@'10.0.0.%' identified by '123' with grant option;"  
 
# db02  
mysql -S /data/3308/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3308/mysql.sock -e "start slave;"  
mysql -S /data/3308/mysql.sock -e "show slave status\G"  
 
# db01  
mysql -S /data/3308/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3308/mysql.sock -e "start slave;"  
mysql -S /data/3308/mysql.sock -e "show slave status\G"  
 
# db02  
mysql -S /data/3310/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3310/mysql.sock -e "start slave;"  
mysql -S /data/3310/mysql.sock -e "show slave status\G"  
 
# db01  
mysql -S /data/3310/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';"  
mysql -S /data/3310/mysql.sock -e "start slave;"  
mysql -S /data/3310/mysql.sock -e "show slave status\G"  
 
Copy  
7.主从状态检测  
mysql -S /data/3307/mysql.sock -e "show slave status\G"  
mysql -S /data/3308/mysql.sock -e "show slave status\G"  
mysql -S /data/3309/mysql.sock -e "show slave status\G"  
mysql -S /data/3310/mysql.sock -e "show slave status\G"  
注:如果中间出现错误,在每个节点进行执行以下命令  
mysql -S /data/3307/mysql.sock -e "stop slave; reset slave all;"  
mysql -S /data/3308/mysql.sock -e "stop slave; reset slave all;"  
mysql -S /data/3309/mysql.sock -e "stop slave; reset slave all;"  
mysql -S /data/3310/mysql.sock -e "stop slave; reset slave all;"  
```  
 
 
## mysql分布式架构介绍  
 
3.png  
分布式架构介绍  
 
 
 
## mycat基础应用  
 
```bash  
 
 
 
range  
取模  
枚举  
hash  
时间  
等等  
```  
 
### 主要配置文件介绍  
 
```basic  
rule.xml  
schema.xml *****,主配置文件  
server.xml  
log4j2.xml *** ,记录日志有关  
*.txt  
```  
 
 
## mycat安装  
 
### 安装Mycat  
 
```basic  
# 预先安装Java运行环境  
yum install -y java  
 
# 下载  
Mycat-server-xxxxx.linux.tar.gz  
 
 
# 解压文件  
[root@db01 application]# tar xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz  
 
# 软件目录结构  
ls  
bin catlet conf lib logs version.txt  
 
# 启动和连接  
配置环境变量  
vim /etc/profile.d/mycat.sh  
export PATH=http://www.likecs.com/application/mycat/bin:$PATH  
source /etc/profile  
启动  
mycat start  
连接mycat:  
mysql -uroot -p123456 -h 127.0.0.1 -P8066  
```  
 
 
### 数据导入  
 
```basic  
# 这里仅作为参考,也可以用其他数据  
[root@db01 ~]# mysql -uroot -p123  
mysql> source /root/world.sql;  
[root@db07 ~]# mysql -uroot -p123  
mysql> source /root/world.sql;  
```  
 
### mycat配置文件浓缩  
 
```basic  
# mycat配置文件有很多多余的,可以进行浓缩  
cd /application/mycat/conf  
mv schema.xml schema.xml.bak  
vim schema.xml  
 
 
<mycat:schema xmlns:mycat="">  
 
 
 
 
select user()  
 
 
 
 
</mycat:schema>  
```  
 
 
### 配置文件介绍  
 
```xml  
# 前期介绍:  
逻辑库schema:  
 
 
 
数据节点:  
 
 
数据主机:  
 
select user()  
 
 
 
 
 
TESTDB:逻辑库名  
balance属性  
负载均衡类型,目前的取值有3种:  
1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。  
2. balance="1",全部的readHost与standby writeHost参与select语句的负载均衡,简单的说,  
当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。  
3. balance="2",所有读操作都随机的在writeHost、readhost上分发。  
 
writeType属性  
负载均衡类型,目前的取值有2种:  
1. writeType="0", 所有写操作发送到配置的第一个writeHost,  
第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为主,切换记录在配置文件中:dnindex.properties .  
2. writeType=“1”,所有写操作都随机的发送到配置的writeHost,但不推荐使用  
 
 
switchType属性  
-1 表示不自动切换  
1 默认值,自动切换  
2 基于MySQL主从同步的状态决定是否切换 ,心跳语句为 show slave status  
datahost其他配置  
 
 
 
maxCon="1000":最大的并发连接数  
minCon="10" :mycat在启动之后,会在后端节点上自动开启的连接线程  
 
tempReadHostAvailable="1"  
这个一主一从时(1个writehost,1个readhost时),可以开启这个参数,如果2个writehost,2个readhost时  
select user() 监测心跳  
```  
 
## Mycat使用  
 
### 读写分离配置  
 
```xml  
vim schema.xml  
 
 
 
<mycat:schema xmlns:mycat="">  
 
 
 
 
select user()  
 
 
 
 
</mycat:schema>  
 
重启mycat  
mycat restart  
 
读写分离测试  
mysql -uroot -p -h 127.0.0.1 -P8066  
show variables like 'server_id';  
begin;  
show variables like 'server_id';  
 
总结:  
 
```  
 
 
### 读写分离和高可用  
 
```xml  
[root@db01 conf]# mv schema.xml schema.xml.rw  
[root@db01 conf]# vim schema.xml  
 
 
 
<mycat:schema xmlns:mycat="">  
 
 
 
 
select user()  
 
 
 
 
 
 
 
</mycat:schema>  
 
真正的 writehost:负责写操作的writehost  
standby writeHost :和readhost一样,只提供读服务  
 
当写节点宕机后,后面跟的readhost也不提供服务,这时候standby的writehost就提供写服务,  
后面跟的readhost提供读服务  
 
测试:  
mysql -uroot -p123456 -h 127.0.0.1 -P 8066  
show variables like 'server_id';  
读写分离测试  
mysql -uroot -p -h 127.0.0.1 -P8066  
show variables like 'server_id';  
show variables like 'server_id';  
show variables like 'server_id';  
begin;  
show variables like 'server_id';  
对db01 3307节点进行关闭和启动,测试读写操作  
```  
 
 
### 垂直分表  
 
```xml  
mv schema.xml schema.xml.ha  
vim schema.xml  
 
 
<mycat:schema xmlns:mycat="">  
 
 
 
 
 
select user()  
 
 
 
 
 
 
 
 
select user()  
 
 
 
 
 
 
 
</mycat:schema>  
 
创建测试库和表:  
[root@db01 conf]# mysql -S /data/3307/mysql.sock -e "create database taobao charset utf8;"  
[root@db01 conf]# mysql -S /data/3308/mysql.sock -e "create database taobao charset utf8;"  
[root@db01 conf]# mysql -S /data/3307/mysql.sock -e "use taobao;create table user(id int,name varchar(20))";  
[root@db01 conf]# mysql -S /data/3308/mysql.sock -e "use taobao;create table order_t(id int,name varchar(20))"  
 
# 测试:  
可登陆到mycat中对表中插入数据,看是否对插入不同表时,数据放入到不同服务器中  
```  
 
 
### 分片(水平拆分)  
 
```xml  
1.前期说明  
分片:对一个"bigtable",比如说t3表  
 
(1)行数非常多,800w  
(2)访问非常频繁  
 
分片的目的:  
(1)将大数据量进行分布存储  
(2)提供均衡的访问路由  
 
分片策略:  
范围 range 800w 1-400w 400w01-800w  
取模 mod 取余数  
枚举  
哈希 hash  
时间 流水  
 
优化关联查询  
全局表  
ER分片  
 
Copy  
2.配置操作  
比如说t3表  
(1)行数非常多,2000w(1-1000w:sh1 1000w01-2000w:sh2)  
(2)访问非常频繁,用户访问较离散  
mv schema.xml schema.xml.1  
vim schema.xml  
 
 
 
 
 
vim rule.xml  
 
 
id  
rang-long  
 
<function  
class="io.mycat.route.function.AutoPartitionByLong">  
autopartition-long.txt  
 
===================================  
vim autopartition-long.txt  
0-10=0  
11-20=1  
 
创建测试表:  
mysql -S /data/3307/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"  
 
mysql -S /data/3308/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"  
 
测试:  
重启mycat  
mycat restart  
mysql -uroot -p123456 -h 127.0.0.1 -P 8066  
insert into t3(id,name) values(1,'a');  
insert into t3(id,name) values(2,'b');  
insert into t3(id,name) values(3,'c');  
insert into t3(id,name) values(4,'d');  
insert into t3(id,name) values(11,'aa');  
insert into t3(id,name) values(12,'bb');  
insert into t3(id,name) values(13,'cc');  
insert into t3(id,name) values(14,'dd');  
```  
 
 
### 取模分片(mod-long)  
 
```xml  
取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点  
vim schema.xml  
vim rule.xml  
2  
 
准备测试环境  
 
创建测试表:  
mysql -S /data/3307/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"  
mysql -S /data/3308/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"  
 
重启mycat  
mycat restart  
 
测试:  
mysql -uroot -p123456 -h10.0.0.52 -P8066  
 
use TESTDB  
insert into t4(id,name) values(1,'a');  
insert into t4(id,name) values(2,'b');  
insert into t4(id,name) values(3,'c');  
insert into t4(id,name) values(4,'d');  
 
分别登录后端节点查询数据  
mysql -S /data/3307/mysql.sock  
use taobao  
select * from t4;  
 
mysql -S /data/3308/mysql.sock  
use taobao  
select * from t4;  
```  
 
 
### 枚举分片  
 
```xml  
t5 表  
id name telnum  
1 bj 1212  
2 sh 22222  
3 bj 3333  
4 sh 44444  
5 bj 5555  
 
sharding-by-intfile  
vim schema.xml  
 
vim rule.xml  
 
name  
hash-int  
 
 
 
 
partition-hash-int.txt  
1  
0  
 
 
partition-hash-int.txt 配置:  
bj=0  
sh=1  
DEFAULT_NODE=1  
columns 标识将要分片的表字段,algorithm 分片函数, 其中分片函数配置中,mapFile标识配置文件名称  
 
准备测试环境  
mysql -S /data/3307/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"  
 
mysql -S /data/3308/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"  
重启mycat  
mycat restart  
mysql -uroot -p123456 -h10.0.0.51 -P8066  
use TESTDB  
insert into t5(id,name) values(1,'bj');  
insert into t5(id,name) values(2,'sh');  
insert into t5(id,name) values(3,'bj');  
insert into t5(id,name) values(4,'sh');  
insert into t5(id,name) values(5,'tj');  
 
```  
 
 
### Mycat全局表  
 
```xml  
a b c d  
join  
t  
 
select t1.name ,t.x from t1  
join t  
select t2.name ,t.x from t2  
join t  
select t3.name ,t.x from t3  
join t  
 
# 使用场景:  
如果你的业务中有些数据类似于数据字典,比如配置文件的配置,  
常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大,  
而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分,  
要在所有的分片上保存一份数据即可,Mycat 在Join操作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表join,  
避免跨库Join,在进行数据插入操作时,mycat将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。  
 
vim schema.xml  
 
后端数据准备  
mysql -S /data/3307/mysql.sock  
use taobao  
create table t_area (id int not null primary key auto_increment,name varchar(20) not null);  
 
mysql -S /data/3308/mysql.sock  
use taobao  
create table t_area (id int not null primary key auto_increment,name varchar(20) not null);  
 
重启mycat  
mycat restart  
 
测试:  
mysql -uroot -p123456 -h10.0.0.52 -P8066  
 
use TESTDB  
insert into t_area(id,name) values(1,'a');  
insert into t_area(id,name) values(2,'b');  
insert into t_area(id,name) values(3,'c');  
insert into t_area(id,name) values(4,'d');  
```  
 
 
### E-R分片  
 
```xml  
A  
join  
B  
为了防止跨分片join,可以使用E-R模式  
A join B  
on a.xx=b.yy  
join C  
on A.id=C.id  
 
 
```  
 
1  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfjzj.html