部署架构图
1 环境搭建
1.1 部署多实例
1、虚拟机环境
两台虚拟机 db01 db02,每个节点创建四个mysql实例:3307、3308、3309、3310
2、删除历史环境数据
pkill mysqld
rm -rf /data/330
mv /etc/my.cnf /etc/my.cnf.bak
*3、创建相关目录初始化数据
mkdir /data/mysql/instance-33{07,08,09,10}/{data,binlog,errorlog} -pv
chown -R mysql.mysql /data/*
mysqld --initialize-insecure --user=mysql --datadir=/data/mysql/instance-3307/data --basedir=/app/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/mysql/instance-3308/data --basedir=/app/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/mysql/instance-3309/data --basedir=/app/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/mysql/instance-3310/data --basedir=/app/mysql
4、准备db01配置文件和启动脚本
cat >/data/mysql/instance-3307/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3307/data
socket=/data/mysql/instance-3307/mysql.sock
port=3307
log-error=/data/mysql/instance-3307/errorlog/mysql.log
log_bin=/data/mysql/instance-3307/binlog/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/mysql/instance-3308/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3308/data
socket=/data/mysql/instance-3308/mysql.sock
port=3308
log-error=/data/mysql/instance-3308/errorlog/mysql.log
log_bin=/data/mysql/instance-3308/binlog/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/mysql/instance-3309/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3309/data
socket=/data/mysql/instance-3309/mysql.sock
port=3309
log-error=/data/mysql/instance-3309/errorlog/mysql.log
log_bin=/data/mysql/instance-3309/binlog/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/mysql/instance-3310/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3310/data
socket=/data/mysql/instance-3310/mysql.sock
port=3310
log-error=/data/mysql/instance-3310/errorlog/mysql.log
log_bin=/data/mysql/instance-3310/binlog/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/mysqld-3307.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3307/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld-3308.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3308/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld-3309.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3309/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld-3310.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3310/my.cnf
LimitNOFILE = 5000
EOF
5、准备db02配置文件和启动脚本
cat >/data/mysql/instance-3307/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3307/data
socket=/data/mysql/instance-3307/mysql.sock
port=3307
log-error=/data/mysql/instance-3307/errorlog/mysql.log
log_bin=/data/mysql/instance-3307/binlog/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/mysql/instance-3308/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3308/data
socket=/data/mysql/instance-3308/mysql.sock
port=3308
log-error=/data/mysql/instance-3308/errorlog/mysql.log
log_bin=/data/mysql/instance-3308/binlog/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/mysql/instance-3309/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3309/data
socket=/data/mysql/instance-3309/mysql.sock
port=3309
log-error=/data/mysql/instance-3309/errorlog/mysql.log
log_bin=/data/mysql/instance-3309/binlog/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/mysql/instance-3310/my.cnf<<EOF
[mysqld]
basedir=/app/mysql
datadir=/data/mysql/instance-3310/data
socket=/data/mysql/instance-3310/mysql.sock
port=3310
log-error=/data/mysql/instance-3310/errorlog/mysql.log
log_bin=/data/mysql/instance-3310/binlog/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/mysqld-3307.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3307/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld-3308.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3308/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld-3309.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3309/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld-3310.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=/app/mysql/bin/mysqld --defaults-file=/data/mysql/instance-3310/my.cnf
LimitNOFILE = 5000
EOF
6、权限修改,启动多实例
chown -R mysql.mysql /data/*
systemctl restart mysqld-3307
systemctl restart mysqld-3308
systemctl restart mysqld-3309
systemctl restart mysqld-3310
mysql -S /data/mysql/instance-3307/mysql.sock -e "show variables like 'server_id'"
mysql -S /data/mysql/instance-3308/mysql.sock -e "show variables like 'server_id'"
mysql -S /data/mysql/instance-3309/mysql.sock -e "show variables like 'server_id'"
mysql -S /data/mysql/instance-3310/mysql.sock -e "show variables like 'server_id'"
1.2 主从及分片规划
1.2.1 主从规划
箭头指向谁是主库
10.0.0.191:3307 <-----> 10.0.0.192:3307
10.0.0.191:3309 ------> 10.0.0.191:3307
10.0.0.192:3309 ------> 10.0.0.192:3307
10.0.0.192:3308 <-----> 10.0.0.191:3308
10.0.0.192:3310 -----> 10.0.0.192:3308
10.0.0.191:3310 -----> 10.0.0.191:3308
1.2.2 分片规划
shard1:
Master:10.0.0.191:3307
slave1:10.0.0.191:3309
Standby Master:10.0.0.192:3307
slave2:10.0.0.192:3309
shard2:
Master:10.0.0.192:3308
slave1:10.0.0.192:3310
Standby Master:10.0.0.191:3308
slave2:10.0.0.191:3310
1.3 主从及分片配置
1.3.1 分片1配置
1.3.1.1 10.0.0.191:3307 <-> 10.0.0.192:3307 互为主从配置
1、db01和db02上创建复制用户
mysql -S /data/mysql/instance-3307/mysql.sock -e "grant replication slave on *.* to repl@'10.0.0.%' identified by 'abc123..';"
mysql -S /data/mysql/instance-3307/mysql.sock -e "grant all on *.* to root@'10.0.0.%' identified by 'abc123..' with grant option;"
2、db01上执行,此时db01为从库加入主库db02
mysql -S /data/mysql/instance-3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.192', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3307/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3307/mysql.sock -e "show slave status\G"
3、在db02上执行,此时db02为从库加入主库db01
mysql -S /data/mysql/instance-3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.191', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3307/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3307/mysql.sock -e "show slave status\G"
1.3.1.2 10.0.0.191:3309 -> 10.0.0.191:3307
将10.0.0.191:3309实例配置为10.0.0.191:3307实例的从库
db01上执行,加入主库10.0.0.191:3307
mysql -S /data/mysql/instance-3309/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.191', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3309/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3309/mysql.sock -e "show slave status\G"
1.3.1.3 10.0.0.192:3309 -> 10.0.0.192:3307
将10.0.0.192:3309实例配置为10.0.0.192:3307实例的从库
db02上执行,加入主库10.0.0.192:3307
mysql -S /data/mysql/instance-3309/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.192', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3309/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3309/mysql.sock -e "show slave status\G"
1.3.2 分片2配置
1.3.2.1 10.0.0.192:3308 <-> 10.0.0.191:3308 互为主从配置
1、在db01和db02上创建复制用户
mysql -S /data/mysql/instance-3308/mysql.sock -e "grant replication slave on *.* to repl@'10.0.0.%' identified by 'abc123..';"
mysql -S /data/mysql/instance-3308/mysql.sock -e "grant all on *.* to root@'10.0.0.%' identified by '123' with grant option;"
2、在db02上执行,此时db02为从库加入主库db01
mysql -S /data/mysql/instance-3308/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.191', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3308/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3308/mysql.sock -e "show slave status\G"
3、在db01上执行,此时db01为从库加入主库db02
mysql -S /data/mysql/instance-3308/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.192', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3308/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3308/mysql.sock -e "show slave status\G"
1.3.2.2 10.0.0.192:3310 -> 10.0.0.192:3308
将10.0.0.192:3310实例配置为10.0.0.192:3308实例的从库
db02上执行,加入主库10.0.0.192:3308
mysql -S /data/mysql/instance-3310/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.192', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3310/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3310/mysql.sock -e "show slave status\G"
1.3.2.3 10.0.0.191:3310 -> 10.0.0.191:3308
将10.0.0.191:3310实例配置为10.0.0.191:3308实例的从库
db01上执行,加入主库10.0.0.191:3308
mysql -S /data/mysql/instance-3310/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.191', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='abc123..';"
mysql -S /data/mysql/instance-3310/mysql.sock -e "start slave;"
mysql -S /data/mysql/instance-3310/mysql.sock -e "show slave status\G"
1.4 检查主从状态
在db01和db02上都执行
mysql -S /data/mysql/instance-3307/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/mysql/instance-3308/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/mysql/instance-3309/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/mysql/instance-3310/mysql.sock -e "show slave status\G"|grep Yes
1.5 Mycat安装部署
1.5.1 安装
1、安装java环境
yum install -y java
2、下载
http://dl.mycat.org.cn/1.6.7.4/Mycat-server-1.6.7.4-release/
3、解压
tar xf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
4、配置环境变量
vim /etc/profile
export PATH=/app/mycat/bin:$PATH
source /etc/profile
5、启动
mycat start
6、连接mycat
mysql -uroot -p123456 -h 127.0.0.1 -P8066
1.5.2 配置文件说明
1、logs目录
wrapper.log ——>mycat启动日志
mycat.log ——>mycat详细工作日志
2、conf目录
schema.xml —-主配置文件(读写分离、高可用、分布式策略定制、节点控制)
server.xml —-mycat软件本身相关的配置
rule.xml —-分片规则配置文件,记录分片规则列表、使用方法等
3、用户创建和数据导入
#db01:
mysql -S /data/mysql/instance-3307/mysql.sock
grant all on *.* to root@'10.0.0.%' identified by 'abc123..';
source /root/world.sql
exit
mysql -S /data/mysql/instance-3308/mysql.sock
grant all on *.* to root@'10.0.0.%' identified by 'abc123..';
source /root/world.sql
1.5.3 schema配置文件重要字段说明
1、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上分发。
2、writetype属性
负载均衡类型,目前的取值有2种:
1)writeType=”0”, 所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为主,切换记录在配置文件中:dnindex.properties
2)writeType=“1”,所有写操作都随机的发送到配置的writeHost,但不推荐使用
3、switchtype属性
- -1 表示不自动切换
- 1 默认值,自动切换
- 2 基于MySQL主从同步的状态决定是否切换 ,心跳语句为 show slave status
4、datahost其他配置
- maxCon=”1000” :最大的并发连接数
- minCon=”10” :mycat在启动之后,会在后端节点上自动开启的连接线程
- tempReadHostAvailable=”1”:这个一主一从时(1个writehost,1个readhost时),可以开启这个参数,如果2个writehost,2个readhost时建议不加此参数
select user() 监测心跳2 读写分离、高可用架构和分片配置
2.1 配置读写分离
一主一从的读写分离,10.0.0.191:3307这个实例为主,10.0.0.191:3309这个实例为从
1、定义配置文件
]# mv schema.xml schema.xml.bak
]# vim schema.xml
2、读写分离测试<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
#mycat逻辑库定义
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="cluster-01">
</schema>
#数据节点定义
<dataNode name="cluster-01" dataHost="host-01" database= "world" />
#后端主机定义
<dataHost name="host-01" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"> <heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3307" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3309" user="root" password="abc123.." />
</writeHost>
</dataHost>
</mycat:schema>
重启mycat
[root@db-01 ~]# mycat restart
链接mycat
[root@db-01 ~]# mysql -uroot -p123456 -h10.0.0.191 -P8066
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 9 |
+-------------+
1 row in set (0.00 sec)
mysql> begin;select @@server_id;commit;
Query OK, 0 rows affected (0.00 sec)
+-------------+
| @@server_id |
+-------------+
| 7 |
+-------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
2.2 Mycat高可用+读写分离
1、定义配置文件
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://mycat.org.cn/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="cluster-01">
</schema>
<dataNode name="cluster-01" dataHost="host-01" database= "world" />
<dataHost name="host-01" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db01" url="10.0.0.191:3307" user="root" password="abc123..">
<readHost host="db02" url="10.0.0.191:3309" user="root" password="abc123.." />
</writeHost>
<writeHost host="db03" url="10.0.0.192:3307" user="root" password="abc123..">
<readHost host="db04" url="10.0.0.192:3309" user="root" password="abc123.." />
</writeHost>
</dataHost>
</mycat:schema>
2、配置段说明
第一个 writeHost:10.0.0.191:3307 真正的写节点负责写操作
第二个 writeHost:10.0.0.192:3307 stanby写节点,负责读,当10.0.0.191:3307宕掉,会切换为真正的写节点
3、测试读写分离
读会落到191:3309、192:3307、192:3309这三个节点上
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 9 |
+-------------+
1 row in set (0.00 sec)
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 19 |
+-------------+
1 row in set (0.00 sec)
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 17 |
+-------------+
1 row in set (0.01 sec)
写只会落到191:3307这个实例上
mysql> begin;select @@server_id; commit;
Query OK, 0 rows affected (0.01 sec)
+-------------+
| @@server_id |
+-------------+
| 7 |
+-------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> begin;select @@server_id; commit;
Query OK, 0 rows affected (0.00 sec)
+-------------+
| @@server_id |
+-------------+
| 7 |
+-------------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
4、测试高可用
模拟故障,将191:3307服务停止,测试主库会切换到192:3307这个实例,写操作也只会落到192:3309这个实例
db01~#] systemctl stop mysqld-3307
读操作只会落到192:3309这个实例
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 19 |
+-------------+
1 row in set (0.00 sec)
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 19 |
+-------------+
1 row in set (0.00 sec)
写操作只会落到192:3307这个实例
mysql> begin;select @@server_id; commit;
Query OK, 0 rows affected (0.00 sec)
+-------------+
| @@server_id |
+-------------+
| 17 |
+-------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> begin;select @@server_id; commit;
Query OK, 0 rows affected (0.00 sec)
+-------------+
| @@server_id |
+-------------+
| 17 |
+-------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
2.3 锤子分片
2.3.1 定义
将数据库当中不同的表存储到不同的数据库实例当中,以达到将写压力分到不同节点的目的,这种拆分方式就叫锤子拆分
2.3.2 功能配置演示
1、配置文件定义
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="slice-01">
<table name="user" dataNode="slice-01"/>
<table name="order_t" dataNode="slice-02"/>
</schema>
<dataNode name="slice-01" dataHost="host-01" database= "taobao" />
<dataNode name="slice-02" dataHost="host-02" database= "taobao" />
<dataHost name="host-01" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3307" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3309" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3307" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3309" user="root" password="abc123.." />
</writeHost>
</dataHost>
<dataHost name="host-02" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3308" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3310" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3308" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3310" user="root" password="abc123.." />
</writeHost>
</dataHost>
</mycat:schema>
2、在db01上创建测试库和表
在两个分片上分别创建相同的taobao库,并在分片1上创建user表,在分片2上创建order_t表
mysql -S /data/mysql/instance-3307/mysql.sock -e "create database taobao charset utf8;"
mysql -S /data/mysql/instance-3308/mysql.sock -e "create database taobao charset utf8;"
mysql -S /data/mysql/instance-3307/mysql.sock -e "use taobao;create table user(id int,name varchar(20))";
mysql -S /data/mysql/instance-3308/mysql.sock -e "use taobao;create table order_t(id int,name varchar(20))"
3、功能测试
当连接mycat后,刚在分片1和分片2创建的表,此时表都在TESTDB这个逻辑库下面
[root@db-01 ~]# mysql -uroot -p123456 -h 10.0.0.191 -P 8066
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 1
Server version: 5.6.29-mycat-1.6.7.6-release-20220221174943 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2019, 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> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.01 sec)
mysql> use TESTDB
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_taobao |
+------------------+
| order_t |
| user |
+------------------+
2 rows in set (0.00 sec)
mysql> insert into user(id,name) values(1,'a'),(2,'b');
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into order_t(id,name) values(3,'c'),(4,'d');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
[root@db-01 ~]# mysql -S /data/mysql/instance-3307/mysql.sock -e "use taobao;show tables;"
+------------------+
| Tables_in_taobao |
+------------------+
| user |
+------------------+
[root@db-01 ~]# mysql -S /data/mysql/instance-3308/mysql.sock -e "use taobao;show tables;"
+------------------+
| Tables_in_taobao |
+------------------+
| order_t |
+------------------+
2.4 水平分片
在锤子拆分的情况下,虽然将表拆分到了不同的数据库实例,达到了缓解单节点写的压力,但是还是会存在热表数据的情况,即对某一张表的写操作较为频繁,这一张表的写操作可能占了整个写操作的80%甚至更高,因此水平分片解决了这种问题,即水平分片就是将一张大表进行拆分成多张小表
水平拆分又分多种拆分策略:
- 范围拆分(range)
- 取模
- 枚举
- hash
- 时间
- 等
2.4.1 范围拆分
1、配置文件
2、编辑rule.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" dataNode="slice-01">
<table name="t3" dataNode="slice-01,slice-02" rule="auto-sharding-long" />
</schema>
<dataNode name="slice-01" dataHost="host-01" database= "taobao" />
<dataNode name="slice-02" dataHost="host-02" database= "taobao" />
<dataHost name="host-01" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3307" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3309" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3307" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3309" user="root" password="abc123.." />
</writeHost>
</dataHost>
<dataHost name="host-02" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3308" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3310" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3308" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3310" user="root" password="abc123.." />
</writeHost>
</dataHost>
</mycat:schema>
找到定义范围拆分的规则auto-sharding-long
3、根据auto-sharding-long规则找到对应的拆分算法
4、修改autopartition-long文件,将拆分范围写入文件
vim autopartition-long.txt
此处只演示20行数据,1-10行数据存储在分片1上面,11-20行数据存储在分片2上面
5、创建测试表1-10=0
11-20=1
6、连接mycat插入数据进行测试mysql -S /data/mysql/instance-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/mysql/instance-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 10.0.0.191 -P 8066
7、在两个分片上查看数据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');
可以看到数据已经分布到了两个分片上 ```sql
[root@db-01 ~]# mysql -S /data/mysql/instance-3307/mysql.sock -e “select from taobao.t3;”
+——+———+
| id | name |
+——+———+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
+——+———+
[root@db-01 ~]# mysql -S /data/mysql/instance-3308/mysql.sock -e “select from taobao.t3;”
+——+———+
| id | name |
+——+———+
| 11 | aa |
| 12 | bb |
| 13 | cc |
| 14 | dd |
+——+———+
<a name="i1Usi"></a>
### 2.4.2 取模拆分
**1、修改配置文件**
```sql
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="slice-01">
<table name="t3" dataNode="slice-01,slice-02" rule="auto-sharding-long" />
<table name="t4" dataNode="slice-01,slice-02" rule="mod-long" />
</schema>
<dataNode name="slice-01" dataHost="host-01" database= "taobao" />
<dataNode name="slice-02" dataHost="host-02" database= "taobao" />
<dataHost name="host-01" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3307" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3309" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3307" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3309" user="root" password="abc123.." />
</writeHost>
</dataHost>
<dataHost name="host-02" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3308" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3310" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3308" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3310" user="root" password="abc123.." />
</writeHost>
</dataHost>
</mycat:schema>
2、编辑rule.xml文件找到取模规则对应的函数
3、修改mod_long函数取模参数
因为只有两个分片,所以这改为了2
4、创建测试表
mysql -S /data/mysql/instance-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/mysql/instance-3308/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"
5、重启mycat并插入测试数据
重启mycat
mycat restart
连接mycat
mysql -uroot -p123456 -h10.0.0.191 -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');
6、登录后端节点查询数据
[root@db-01 ~]# mysql -S /data/mysql/instance-3307/mysql.sock -e "select * from taobao.t4;"
+----+------+
| id | name |
+----+------+
| 2 | b |
| 4 | d |
+----+------+
[root@db-01 ~]# mysql -S /data/mysql/instance-3308/mysql.sock -e "select * from taobao.t4;"
+----+------+
| id | name |
+----+------+
| 1 | a |
| 3 | c |
+----+------+
2.4.3 枚举拆分
1、配置文件
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="slice-01">
<table name="t3" dataNode="slice-01,slice-02" rule="auto-sharding-long" />
<table name="t4" dataNode="slice-01,slice-02" rule="mod-long" />
<table name="t4" dataNode="slice-01,slice-02" rule="sharding-by-intfile" />
</schema>
<dataNode name="slice-01" dataHost="host-01" database= "taobao" />
<dataNode name="slice-02" dataHost="host-02" database= "taobao" />
<dataHost name="host-01" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3307" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3309" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3307" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3309" user="root" password="abc123.." />
</writeHost>
</dataHost>
<dataHost name="host-02" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.0.191:3308" user="root" password="abc123..">
<readHost host="db2" url="10.0.0.191:3310" user="root" password="abc123.." />
</writeHost>
<writeHost host="db3" url="10.0.0.192:3308" user="root" password="abc123..">
<readHost host="db4" url="10.0.0.192:3310" user="root" password="abc123.." />
</writeHost>
</dataHost>
</mycat:schema>
2、编辑rule.xml文件找到枚举分片规则
修改列值为name,columns 标识将要分片的表字段
3、查看hash-int函数
需要编辑mapFile文件,partition-hash-int.txt,mapFile标识配置文件名称
4、编辑partition-hash-int.txt文件
vim partition-hash-int.txt
bj=0
sh=1
DEFAULT_NODE=1
5、创建测试表
mysql -S /data/mysql/instance-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/mysql/instance-3308/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"
6、重启mycat并插入测试数据
重启mycat
mycat restart
连接mycat
mysql -uroot -p123456 -h10.0.0.191 -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');
7、登录后端节点查询数据
[root@db-01 ~]# mysql -S /data/mysql/instance-3307/mysql.sock -e "select * from taobao.t5;"
+----+------+
| id | name |
+----+------+
| 1 | bj |
| 3 | bj |
| 5 | tj |
+----+------+
[root@db-01 ~]# mysql -S /data/mysql/instance-3308/mysql.sock -e "select * from taobao.t5;"
+----+------+
| id | name |
+----+------+
| 2 | sh |
| 4 | sh |
+----+------+