MyCAT基础架构图

双主双从结构

MyCAT基础架构准备

准备环境

 环境准备:
 两台虚拟机 db01 db02
 每台创建四个mysql实例:3307 3308 3309 3310

删除历史环境

 pkill mysqld
rm -rf /data/330*
\mv /etc/my.cnf /etc/my.cnf.bak

初始化数据

 mkdir /data/33{07..10}/data -p
mysqld --initialize-insecure --user=mysql --datadir=/data/3307/data --basedir=/usr/local/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3308/data --basedir=/usr/local/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3309/data --basedir=/usr/local/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3310/data --basedir=/usr/local/mysql 配置文件 ========db01============== cat >/data/3307/my.cnf<<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3307/data
socket=/data/3307/mysql.sock
port=3307
log-error=/data/3307/mysql.log
log_bin=/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=/usr/local/mysql
datadir=/data/3308/data
port=3308
socket=/data/3308/mysql.sock
log-error=/data/3308/mysql.log
log_bin=/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=/usr/local/mysql
datadir=/data/3309/data
socket=/data/3309/mysql.sock
port=3309
log-error=/data/3309/mysql.log
log_bin=/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=/usr/local/mysql
datadir=/data/3310/data
socket=/data/3310/mysql.sock
port=3310
log-error=/data/3310/mysql.log
log_bin=/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=/usr/local/mysql/bin/mysqld --defaults-file=/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=/usr/local/mysql/bin/mysqld --defaults-file=/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=/usr/local/mysql/bin/mysqld --defaults-file=/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=/usr/local/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf
LimitNOFILE = 5000
EOF ========db02=============== cat >/data/3307/my.cnf<<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3307/data
socket=/data/3307/mysql.sock
port=3307
log-error=/data/3307/mysql.log
log_bin=/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=/usr/local/mysql
datadir=/data/3308/data
port=3308
socket=/data/3308/mysql.sock
log-error=/data/3308/mysql.log
log_bin=/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=/usr/local/mysql
datadir=/data/3309/data
socket=/data/3309/mysql.sock
port=3309
log-error=/data/3309/mysql.log
log_bin=/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=/usr/local/mysql
datadir=/data/3310/data
socket=/data/3310/mysql.sock
port=3310
log-error=/data/3310/mysql.log
log_bin=/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=/usr/local/mysql/bin/mysqld --defaults-file=/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=/usr/local/mysql/bin/mysqld --defaults-file=/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=/usr/local/mysql/bin/mysqld --defaults-file=/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=/usr/local/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf
LimitNOFILE = 5000
EOF

启动多实例

 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'"

配置主从环境

 shard1
10.0.0.51:3307 <-----> 10.0.0.52:3307
# db02
mysql -S /data/3307/mysql.sock -e "create user repl@'10.0.0.%' identified with mysql_native_password by '123'; grant replication slave on *.* to repl@'10.0.0.%'; "
mysql -S /data/3307/mysql.sock -e "create user root@'10.0.0.%' identified with mysql_native_password by '123'; grant all on *.* to root@'10.0.0.%'; "
# 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"|grep Running
# 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" |grep Running
10.0.0.51:3309 ------> 10.0.0.51:3307
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"|grep Running
10.0.0.52:3309 ------> 10.0.0.52:3307
# 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"|grep Running
====================================================================


# shard2
## 10.0.0.52:3308 <-----> 10.0.0.51:3308
# db01
mysql -S /data/3308/mysql.sock -e "create user repl@'10.0.0.%' identified with mysql_native_password by '123'; grant replication slave on *.* to repl@'10.0.0.%';"
mysql -S /data/3308/mysql.sock -e "create user root@'10.0.0.%' identified with mysql_native_password by '123'; grant all on *.* to root@'10.0.0.%'; "

# 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" |grep Running
# 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"|grep Running
## 10.0.0.52:3310 -----> 10.0.0.52:3308
# 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" |grep Running
##10.0.0.51:3310 -----> 10.0.0.51:3308
# 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"|grep Running

检测主从状态

 mysql -S /data/3307/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/3308/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/3309/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/3310/mysql.sock -e "show slave status\G"|grep Yes

注:如果中间出现错误,在每个节点进行执行以下命令,从配置主从环境开始执行 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;"

节点主从规划

 箭头指向谁是主库
     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

MySQL分布式架构介绍

1. schema拆分及业务分库
2. 垂直拆分-分库分表
3. 水平拆分-分片

企业代表产品

 360 Atlas-Sharding
 Alibaba cobar
 Mycat
 TDDL
 Heisenberg
 Oceanus
 Vitess
 OneProxy
 DRDS

MyCAT安装

开源组织和社区开发人员,在淘宝cobar(TDDL)基础上二次开发,Mycat后来被爱可生改写成了DBLE

安装Java运行环境

 yum install -y java

下载

http://dl.mycat.org.cn/1.6.7.4/

http://dl.mycat.org.cn/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz

解压文件

 [root@db02 opt]#rz
[root@db02 opt]# tar xf Mycat-server-1.6.7.4-release-20200105164103-linux_.tar.gz

软件目录结构

 ls
bin catlet conf lib logs version.txt

启动和连接

 配置环境变量
 [root@db02 opt]#vim /etc/profile
export PATH=/opt/mycat/bin:$PATH
[root@db02 opt]#source /etc/profile

 启动
 [root@db02 opt]#mycat start

 连接mycat:    
 [root@db02 opt]#mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password
8.0之前[root@db02 opt]#mysql -uroot -p123456 -h10.0.0.52 -P8066

配置文件介绍

 bin 目录
 程序目录
 conf
 配置文件目录
 schema.xml
 主配置文件:节点信息、读写分离、高可用设置、调用分片策略..
 rule.xml
 分片策略的定义、功能、使用用方法
 server.xml
 mycat服务有关配置: 用户、网络、权限、策略、资源...
 xx.txt文件
 分片参数定义文件
 log4j2.xml
 Mycat 相关日志记录配置
 logs
 wrapper.log: 启动日志  
 mycat.log : 工作日志

应用环境准备

用户创建及数据库导入

 schema.xml配置文件结构
 [root@db02 conf]# cd /opt/mycat/conf/
[root@db02 conf]#mv schema.xml schema.xml.bak
[root@db02 conf]#vim 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" dataNode="dn1">
</schema>
<dataNode name="dn1" dataHost="localhost1" database= "world" />
<dataHost name="localhost1" 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.51:3307" user="root" password="123">
<readHost host="db2" url="10.0.0.51:3309" user="root" password="123" />
</writeHost>
</dataHost>
</mycat:schema>
 ########################测试环境准备
 [root@db02 conf]# mysql -S /data/3307/mysql.sock -e  "source /root/world.sql"
[root@db02 conf]# mysql -S /data/3308/mysql.sock -e "source /root/world.sql"
[root@db02 conf]# mycat restart 重启mycat
     
 ######################## 读写分离测试    
  # 测试读
 mysql -uroot -p123456 -h 10.0.0.52 -P8066 --default-auth=mysql_native_password  -e "select @@server_id;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+
| @@server_id |
+-------------+
| 9 |
+-------------+
# 测试写
mysql -uroot -p123456 -h 10.0.0.52 -P8066 --default-auth=mysql_native_password -e "begin ; select @@server_id;commit;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+
| @@server_id |
+-------------+
| 7 |
+-------------+

         
 ############################总结:
 以上案例实现了1主1从的读写分离功能,写操作落到主库,读操作落到从库.如果主库宕机,从库不能在继续提供服务了。

配置文件详细介绍

逻辑库:schema

 <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
</schema>

数据节点:datanode

 <dataNode name="dn1" dataHost="localhost1" database= "world" />

数据主机:datahost(w和r)

 <dataHost name="localhost1" 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.51:3307" user="root" password="123">
<readHost host="db2" url="10.0.0.52:3309" user="root" password="123" />
</writeHost>
</dataHost>
 

配置读写分离及高可用

 [root@db02 conf]# mv schema.x
 [root@db02 conf]# mv schema.xml schema.xml.rw
[root@db02 conf]# vim 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" dataNode="sh1">
</schema>
<dataNode name="sh1" dataHost="oldguo1" database= "world" />
<dataHost name="oldguo1" 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.51:3307" user="root" password="123">
<readHost host="db2" url="10.0.0.51:3309" user="root" password="123" />
</writeHost>
<writeHost host="db3" url="10.0.0.52:3307" user="root" password="123">
<readHost host="db4" url="10.0.0.52:3309" user="root" password="123" />
</writeHost>
</dataHost>
</mycat:schema>
ml schema.xml.rw
[root@db02 conf]# vim 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" dataNode="sh1">
</schema>
<dataNode name="sh1" dataHost="oldguo1" database= "world" />
<dataHost name="oldguo1" 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.51:3307" user="root" password="123">
<readHost host="db2" url="10.0.0.51:3309" user="root" password="123" />
</writeHost>
<writeHost host="db3" url="10.0.0.52:3307" user="root" password="123">
<readHost host="db4" url="10.0.0.52:3309" user="root" password="123" />
</writeHost>
</dataHost>
</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节点进行关闭和启动,测试读写操作

重启

[root@db02 conf]#mycat restart

测试读(三读)

 [root@db02 conf]# mysql -uroot -p123456 -h 10.0.0.52 -P8066 --default-auth=mysql_native_password  -e "select @@server_id;"
+-------------+
| @@server_id |
+-------------+
| 19 |
+-------------+
+-------------+
| @@server_id |
+-------------+
| 17 |
+-------------+
+-------------+
| @@server_id |
+-------------+
| 9 |
+-------------+

测试写(一写)

 [root@db02 conf]# mysql -uroot -p123456 -h 10.0.0.52 -P8066 --default-auth=mysql_native_password  -e "begin ; select @@server_id;commit;"
+-------------+
| @@server_id |
+-------------+
| 7 |
+-------------+

测试高可用

[root@db01 ~]# systemctl stop mysqld3307
[root@db02 conf]# mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password -e "select @@server_id;"
+-------------+
| @@server_id |
+-------------+
| 19 |
+-------------+

[root@db02 conf]# mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password -e "begin ; select @@server_id;commit;"
+-------------+
| @@server_id |
+-------------+
| 17 |
+-------------+
[root@db01 ~]# systemctl start mysqld3307
[root@db02 conf]# mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password -e "select @@server_id;"
+-------------+
| @@server_id |
+-------------+
| 19 |
+-------------+
+-------------+
| @@server_id |
+-------------+
| 7 |
+-------------+
+-------------+
| @@server_id |
+-------------+
| 9 |
+-------------+

[root@db02 conf]# mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password -e "begin ; select @@server_id;commit;"
+-------------+
| @@server_id |
+-------------+
| 17 |
+-------------+

配置中的属性介绍:

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其他配置

 <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">
maxCon="1000":最大的并发连接数
minCon="10" :mycat在启动之后,会在后端节点上自动开启的连接线程
tempReadHostAvailable="1"
这个一主一从时(1个writehost,1个readhost时),可以开启这个参数,如果2个writehost,2个readhost时
<heartbeat>select user()</heartbeat> 监测心跳

Mycat 分布式架构----垂直分表

 taobao库:   user (sh1),order_t(sh2)   ,others(sh3)
[root@db02 conf]# mv schema.xml schema.xml.ha
[root@db02 conf]# vim 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" dataNode="sh1">
<table name="user" dataNode="sh1"/>
<table name="order_t" dataNode="sh2"/>
</schema>
<dataNode name="sh1" dataHost="oldguo1" database= "taobao" />
<dataNode name="sh2" dataHost="oldguo2" database= "taobao" />
<dataHost name="oldguo1" 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.51:3307" user="root" password="123">
<readHost host="db2" url="10.0.0.51:3309" user="root" password="123" />
</writeHost>
<writeHost host="db3" url="10.0.0.52:3307" user="root" password="123">
<readHost host="db4" url="10.0.0.52:3309" user="root" password="123" />
</writeHost>
</dataHost> <dataHost name="oldguo2" 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.51:3308" user="root" password="123">
<readHost host="db2" url="10.0.0.51:3310" user="root" password="123" />
</writeHost>
<writeHost host="db3" url="10.0.0.52:3308" user="root" password="123">
<readHost host="db4" url="10.0.0.52:3310" user="root" password="123" />
</writeHost>
</dataHost>
</mycat:schema>

创建测试库和表

 [root@db02 conf]# mysql -S /data/3307/mysql.sock -e "create database taobao charset utf8;"
[root@db02 conf]# mysql -S /data/3308/mysql.sock -e "create database taobao charset utf8;"
[root@db02 conf]# mysql -S /data/3307/mysql.sock -e "use taobao;create table user(id int,name varchar(20))";
[root@db02 conf]# mysql -S /data/3308/mysql.sock -e "use taobao;create table order_t(id int,name varchar(20))";

重启mycat

 [root@db02 conf]# mycat restart

mycat数据插入

 [root@db02 conf]# mysql -uroot -p123456 -h 10.0.0.52  -P 8066 --default-auth=mysql_native_password
insert into user values(1,'a');
insert into user values(2,'b');
insert into user values(3,'c');
commit;
insert into order_t values(1,'x'),(2,'y');
commit;
show databases;
use TESTDB;
show tables
select * from order_t;
+------+------+
| id | name |
+------+------+
| 1 | x |
| 2 | y |
+------+------+
2 rows in set (0.05 sec)

mysql> select * from user;
+------+------+
| id | name |
+------+------+
| 1 | a |
| 2 | b |
| 3 | c |
+------+------+ [root@db02 conf]# mysql -S /data/3307/mysql.sock -e "show tables from taobao"
+------------------+
| Tables_in_taobao |
+------------------+
| user |
+------------------+
[root@db02 conf]# mysql -S /data/3308/mysql.sock -e "show tables from taobao"
+------------------+
| Tables_in_taobao |
+------------------+
| order_t |
+------------------+
[root@db02 conf]# mysql -S /data/3307/mysql.sock -e "select * from taobao.user"
+------+------+
| id | name |
+------+------+
| 1 | a |
| 2 | b |
| 3 | c |
+------+------+
[root@db02 conf]# mysql -S /data/3308/mysql.sock -e "select * from taobao.order_t"
+------+------+
| id | name |
+------+------+
| 1 | x |
| 2 | y |
+------+------

MyCAT核心特性——分片(水平拆分)

 分片:对一个"bigtable",比如说t3表
 (1)行数非常多,800w
 (2)访问非常频繁
 分片的目的:
 (1)将大数据量进行分布存储
 (2)提供均衡的访问路由
 分片策略:
 几乎融合经典业务中大部分的分片策略。Mycat已经开发了相应算法,非常方便调用。
 范围分片
 取模
 枚举
 日期
 HASH
 等。
 分片键: 作为分片条件的列。

范围分片(range)

  比如说t3表
 行数非常多,2000w(1-1000w:sh1   1000w01-2000w:sh2)
 访问非常频繁,用户顺序访问较多

定制分片策略

 [root@db02 conf]#cp schema.xml schema.xml.1
[root@db02 conf]#vim schema.xml
<table name="user" dataNode="sh1"/>
<table name="order_t" dataNode="sh2"/>
下方添加:
<table name="t3" dataNode="sh1,sh2" rule="auto-sharding-long" />
</schema>

定义和使用分片策略

 vim rule.xml
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>

定义范围

 [root@db02 conf]#vim autopartition-long.txt
0-10=0
10-20=1

创建测试表

 [root@db02 conf]# 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);"
[root@db02 conf]# 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并测试

 [root@db02 conf]# mycat restart
[root@db02 conf]# mysql -uroot -p123456 -h 10.0.0.52 -P 8066 --default-auth=mysql_native_password
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');
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
mysql> use TESTDB;
mysql> show tables;
+------------------+
| Tables_in_taobao |
+------------------+
| order_t |
| t3 |
| user |
+------------------+
#####逻辑上合并
mysql> select * from t3;
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
| 11 | aa |
| 12 | bb |
| 13 | cc |
| 14 | dd |
+----+------+

###物理上分开
[root@db02 conf]# mysql -S /data/3308/mysql.sock -e "select * from taobao.t3"
+----+------+
| id | name |
+----+------+
| 11 | aa |
| 12 | bb |
| 13 | cc |
| 14 | dd |
+----+------+
[root@db02 conf]# mysql -S /data/3307/mysql.sock -e "select * from taobao.t3"
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |

 +----+------+

取模分片(mod-long)

 1%3 1
 2%3 2
 3%3 0
 4%3 1
 5%3 2
 任何正整数数字和N(正整数)取模,得的值永远都是 0~N-1
 id % 分片数量取模
 N % 5 =  0-4   idx

修改配置文件

 取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点
 [root@db02 conf]#vim schema.xml
 添加:....t3之后
    <table name="t4" dataNode="sh1,sh2" rule="mod-long" />

查看和定义分片使用

 [root@db02 conf]#vim rule.xml
<property name="count">3</property>
<property name="count">2</property> #将3修改为2

准备测试环境

创建测试表

 [root@db02 conf]# 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);"
[root@db02 conf]# 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

 [root@db02 conf]# mycat restart

测试

 [root@db01 ~]# mysql -uroot -p123456 -h 10.0.0.52 -P8066 --default-auth=mysql_native_password
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');
insert into t4(id,name) values(6,'x'),(8,'y'),(10,'z');

登录端节点查询数据

 [root@db02 conf]# mysql -S /data/3308/mysql.sock -e "select * from taobao.t4"
+----+------+
| id | name |
+----+------+
| 1 | a |
| 3 | c |
+----+------+
[root@db02 conf]# mysql -S /data/3307/mysql.sock -e "select * from taobao.t4"
+----+------+
| id | name |
+----+------+
| 2 | b |
| 4 | d |
| 6 | x |
| 8 | y |
| 10 | z |
+----+------+

枚举分片(区域,zone)

 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
添加t4之后
<table name="t5" dataNode="sh1,sh2" rule="sharding-by-intfile" />

应用分片策略

 vim rule.xml
<tableRule name="sharding-by-intfile">
<rule>
<columns>name</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
</function>
vim partition-hash-int.txt 配置:
bj=0
sh=1
DEFAULT_NODE=1 #默认分

准备测试环境

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.52 -P8066 --default-auth=mysql_native_password
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');

测试

 mysql -S /data/3308/mysql.sock -e "select * from taobao.t5"
+----+------+
| id | name |
+----+------+
| 2 | sh |
| 4 | sh |
| 5 | tj |
+----+------+
mysql -S /data/3307/mysql.sock -e "select * from taobao.t5"
+----+------+
| id | name |
+----+------+
| 1 | bj |
| 3 | bj |
+----+------+

Mycat全局表

 a   b   c  d   .....
join
t
a
id name age
1 zs 18 sh1
id addr aid
1001 bj 1
1002 sh 2
2 ls 19 sh2
id addr aid
1001 bj 1
1002 sh 2
t
id addr aid
1001 bj 1
1002 sh 2

使用场景

如果你的业务中有些数据类似于数据字典,比如配置文件的配置, 常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大, 而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分, 要在所有的分片上保存一份数据即可,Mycat 在Join操作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表join, 避免跨库Join,在进行数据插入操作时,mycat将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。

设置全局表策略

 [root@db02 conf]#vim schema.xml
<table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2" />

后端数据准备

[root@db02 conf]# mysql -S /data/3307/mysql.sock -e "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 -e "use taobao;create table t_area (id int not null primary key auto_increment,name varchar(20) not null);"

重启mycat

 [root@db02 conf]# mycat restart

测试

 [root@db02 conf]# mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password 

 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');
mysql -S /data/3308/mysql.sock -e "select * from taobao.t_area"
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
+----+------+
mysql -S /data/3307/mysql.sock -e "select * from taobao.t_area"
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
+----+------+

E-R分片(有关联的表)

 a
join
b
on a.xx =b.yy
a
id name
--------------
1 a sh1
3 c
----------------
2 b sh2
4 d

b
id addr aid
1001 bj 1 sh1
1002 sh 2

1003 tj 3 sh2
1004 wh 4

修改配置文件

 vim schema.xml
<table name="a" dataNode="sh1,sh2" rule="mod-long_oldguo">
<childTable name="b" joinKey="aid" parentKey="id" />
</table>

修改分片策略

 vim rule.xml
#mod-long之后
<tableRule name="mod-long_oldguo">
<rule>
<columns>id</columns>
<algorithm>mod-long_oldguo</algorithm>
</rule>
</tableRule>

###<property name="count">2</property>
</function>
添加之后
<function name="mod-long_oldguo" class="io.mycat.route.function.PartitionByMod"> <!-- how many data nodes -->
<property name="count">2</property>
</function>

创建测试表

mysql -S /data/3307/mysql.sock -e "use taobao;create table a
(id int not null primary key auto_increment,name varchar(20) not null);"
mysql -S /data/3307/mysql.sock -e "use taobao;create table b
(id int not null primary key auto_increment,addr varchar(20) not null ,aid int );"
mysql -S /data/3308/mysql.sock -e "use taobao;create table a
(id int not null primary key auto_increment,name varchar(20) not null);"
mysql -S /data/3308/mysql.sock -e "use taobao;create table b
(id int not null primary key auto_increment,addr varchar(20) not null ,aid int );"

重启mycat 测试

 mycat restart
mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password
use TESTDB
insert into a(id,name) values(1,'a');
insert into a(id,name) values(2,'b');
insert into a(id,name) values(3,'c');
insert into a(id,name) values(4,'d');
insert into a(id,name) values(5,'e');
insert into b(id,addr,aid) values(1001,'bj',1);
insert into b(id,addr,aid) values(1002,'sj',3);
insert into b(id,addr,aid) values(1003,'sd',4);
insert into b(id,addr,aid) values(1004,'we',2);
insert into b(id,addr,aid) values(1005,'er',5);

后端数据节点数据分布

 mysql -S /data/3307/mysql.sock  -e "select * from taobao.a"
+----+------+
| id | name |
+----+------+
| 2 | b |
| 4 | d |
+----+------+
mysql -S /data/3307/mysql.sock -e "select * from taobao.b" +------+------+------+
| id | addr | aid |
+------+------+------+
| 1003 | sd | 4 |
| 1004 | we | 2 |
+------+------+------+
mysql -S /data/3308/mysql.sock -e "select * from taobao.a"
+----+------+
| id | name |
+----+------+
| 1 | a |
| 3 | c |
| 5 | e |
+----+------+
mysql -S /data/3308/mysql.sock -e "select * from taobao.b"
+------+------+------+
| id | addr | aid |
+------+------+------+
| 1001 | bj | 1 |
| 1002 | sj | 3 |
| 1005 | er | 5 |
+------+------+------+
 

MySQL之九---分布式架构(Mycat/DBLE)的更多相关文章

  1. MySQL 部署分布式架构 MyCAT (二)

    安装 MyCAT 安装 java 环境(db1) yum install -y java 下载 Mycat-server-1.6.5-release-20180122220033-linux.tar. ...

  2. MySQL 部署分布式架构 MyCAT (五)

    分片(水平拆分) 4.全局表 业务使用场景: 如果你的业务中有些数据类似于数据字典,比如配置文件的配置, 常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大, 而且大部分的业务场景都会用到 ...

  3. MySQL 部署分布式架构 MyCAT (四)

    分片(水平拆分) 2.取模分片(mod-long) cd /data/mycat/conf cp schema.xml schema.xml.rang-long vi schema.xml <? ...

  4. MySQL 部署分布式架构 MyCAT (三)

    配置垂直分表 修改 schema.xml (db1) cd /data/mycat/conf cp schema.xml schema.xml.rwh # 修改配置 vi schema.xml < ...

  5. MySQL 部署分布式架构 MyCAT (一)

    架构 环境 主机名 IP db1 192.168.31.205 db2 192.168.31.206 前期准备 开启防火墙,安装配置 mysql (db1,db2) firewall-cmd --pe ...

  6. Mysql 高可用(MHA)-读写分离(Atlas)-分布式架构(Mycat)

    Mysql 高可用(MHA)-读写分离(Atlas) 1. 搭建主从复制(一主两从) 1.1 准备环境 1 主库:10.0.0.51/db01 2 从库:10.0.0.52/db02,10.0.0.5 ...

  7. 分享 : 警惕MySQL运维陷阱:基于MyCat的伪分布式架构

    分布式数据库已经进入了全面快速发展阶段.这种发展是与时俱进的,与人的需求分不开,因为现在信息时代的高速发展,导致数据量和交易量越来越大.这种现象首先导致的就是存储瓶颈,因为MySQL数据库实质上还是一 ...

  8. 转:三思!大规模MySQL运维陷阱之基于MyCat的伪分布式架构

    在微信公众号看到一篇关于mycat的文章,觉得分析的很不错,给大家分享一下 三思!大规模MySQL运维陷阱之基于MyCat的伪分布式架构 原文链接:https://mp.weixin.qq.com/s ...

  9. MySQL for OPS 10:MyCAT 分布式架构

    写在前面的话 在学习的索引的时候,有提到,当数据表数据达到 800W 的时候,索引的性能就开始逐步下降.对于一个公司而言,主要业务数据表达到 1000W 都很容易.同时这张表一般都是业务常用的表,操作 ...

随机推荐

  1. Dire Wolf——HDU5115

    Dire wolves, also known as Dark wolves, are extraordinarily large and powerful wolves. Many, if not ...

  2. Revit二次开发环境配置(Revit 2020 +Visual Studio 2019)

    Revit二次开发环境搭建(Revit 2019+Visual Studio 2017)准备内容 Revit 2019开发环境的搭建,需要安装的内容如下: Revit 2019(主要的开发环境) Vi ...

  3. 流程的python PDF高清版

    免费下载链接:https://pan.baidu.com/s/1qcPjLlFXhVXosIGBKHVVXQ 提取码:qfiz

  4. 国产网络测试仪MiniSMB - 如何配置VLAN数据流

    国产网络测试仪MiniSMB(www.minismb.com)是复刻smartbits的IP网络性能测试工具,是一款专门用于测试智能路由器,网络交换机的性能和稳定性的软硬件相结合的工具.可以通过此以太 ...

  5. Python基础--核心数据类型

    python的核心数据类型: Number 数字(整数,浮点数,复数,布尔型数) String 字符串 List 列表 Tuple 元组 Dictionary 字典 Set 集合 1. 整数(整型数) ...

  6. GO - 高级编程

    https://books.studygolang.com/gopl-zh/ https://chai2010.cn/advanced-go-programming-book/

  7. spring-cloud-netflix-eureka-server

    一.构建springcloud父pom工程,管理版本 pom.xml <?xml version="1.0" encoding="UTF-8"?> ...

  8. Verilog基础语法总结

    去年小学期写的,push到博客上好了 Verilog 的基本声明类型 wire w1; // 线路类型 reg [-3:4] r1; // 八位寄存器 integer mem[0:2047]; // ...

  9. Sentry 中文版

    Sentry 中文版 汉化 https://sentry.io/settings/account/details/ 打开用户设置 User settings 语言选择中文 Simplified Chi ...

  10. set CSS style in js solutions All In One

    set CSS style in js solutions All In One css in js set each style property separately See the Pen se ...