day11-02-MyCAT分布式架构
数据库分布式架构方式
MyCAT官方网站:http://www.mycat.org.cn/
一、什么是MyCat
1.1
MyCat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户开源把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。
MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储。而在最终用户看来,无论是哪种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。
1.2
- 一个彻底开源的,面向企业应用开发的大数据库集群
- 支持事务、ACID
- 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
- 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
- 结合传统数据库和新型分布式数据仓库
- 数据库中间件产品
1.3
MyCat是一个开源的分布式数据库系统,但是由于真正的数据库需要存储引擎,而Mycat并没有存储引擎,所以并不是完全意义的分布式数据库系统。
Mycat是一个数据库中间件,也可以理解为是数据库代理。在架构体系中是位于数据库和应用层之间的一个组件,并且对于应用层是透明的,即数据库感受不到mycat的存在,认为是直接连的mysql数据库(实际上是连接的mycat,mycat实现了mysql的原生协议)
mycat的三大功能:分表、读写分离、主从切换
MyCAT 属于 中间件代理层
二、MyCat的关键特性
支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常见SQL语法
支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群
支持前端作为MySQL通用代理,后端JDBC方式支持Oracle、DB2、SQL Server、mongodb
支持库内分表
三、MyCat原理
MyCat就是一个数据库中间件,数据库的代理,它屏蔽了物理数据库,应用连接MyCat,然后MyCat再连接物理数据库。
通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明
优点:通用,对应用透明,改造少
缺点:实现难度大,有二次转发性能损失,单机损失30%左右
MyCat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

1.application提交sql后,经过sql解析,优化,路由,解析为对应的sql指令,交给具体的sql机器执行
2.各节点的计算结果进行结果集合并
3.manager负责master的集群管理,内存管理等
四、MyCat的核心技术
数据库分片指:通过某种特定的条件,将我们存放在一个数据库中的数据分散存放在不同的多个数据库(主机)中,这样来达到分散单台设备的负载
MyCAT通过定义表的分片规则来实现分片,每个table可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法。
1.Schema:逻辑库,与MySQL中的Datebase(数据库)对应,一个逻辑库中定义了所包括的Table。
2.Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。
3.DataNode:MyCat的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上。
4.DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上。
5.分片规则:前面奖励数据切分,一个大表分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难
1、垂直拆分:(--单库性能瓶颈)
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面
比如把业务上的3张表,分别拆分到不同的物理节点
优点:拆分后业务清晰,拆分规则明确;
系统之间整合或扩展容易;
数据维护简单
缺点:部分业务表无法join,只能通过接口方式解决,提高了系统复杂度;
受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高;
事务处理复杂
2、水平拆分 :
比如把一张热点表,按照策略,拆分到独立的几个节点里
按照某个字段的某种规则来分散到多个库之中,每个表包含一部分数据。简单来说,可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,主要有分表、分库两种模式
优点:不存在单库大数据,高并发的性能瓶颈;
对应用透明,应用端改造较少;
按照合理拆分规则拆分;
join操作基本避免跨库,提高了系统的稳定性跟负载能力
缺点:拆分规则难以抽象;
分片事务一致性难以解决;
数据多次扩展难度跟维护量极大
跨库join性能较差
拆分策略
range 范围拆分 ,比如取id列,按照id 1000-2000分一个,2000-4000分一个
取模、枚举、hash、时间、等等
分表
对于数据量很大的表(千万级以上),mysql性能会有很大下降,因此尽量控制在每张表的大小在百万级别。对于数据量很大的一张表,可以考虑将这些记录按照一定的规则放到不同的数据库里面。这样每个数据库的数据量不是太大,性能也不会有太大损失。
mycat分表的实现:首先在mycat的scheme.xml中配置逻辑表,并且在配置中说明此表在哪几个物理库上。此逻辑表的名字与真实数据库中的名字一致!然后需要配置分片规则,即按照什么逻辑分库!
读写分离
经过统计发现,对数据库的大量操作是读操作,一般占到所有操作70%以上。所以做读写分离还是很有必要的,如果不做读写分离,那么从库也是一种很大的浪费。
MyCat基本元素
1.逻辑库:MyCat中存在,对应用来说相当于mysql数据库,后端困难对应了多个物理数据库,逻辑库中不保存数据
2.逻辑表:逻辑库中的表,对应用来说相当于mysql的数据表,后端困难对应多个物流数据库中的表,也不保存数据
逻辑表分类
1)分片表:进行了水平切分的表,具有相同表结构但存储在不同数据库中的表,所有分片表的集合才是一张完整的表
分片表,是指那些有很大数据,需要切分到多个数据库的表,这样每个分片都有一部分数据,所有分片构成了完整的数据。
<table name="t_goods" primaryKey="vid" autolncrement="true" dataNode="dn1,dn2" rule="rule1" />
2)非分片表:垂直切分的表,一个数据库中就保存了一张完整的表
一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。
<table name="t_node" primaryKey="vid" autolncrement="true" dataNode="dn1" />
3)全局表:所有分片数据库中都存在的表,如字典表,数据量少,由MyCat来进行维护更新
意义:例如国家列表,存量小(100w以下的数据表),需要经常和其他表进行join,所以可以用空间换取时间,防止跨库访问,则所有分片上面都放入全局表。
一个真实的业务系统中,往往存在大量的类似字典表的表,这些表基本上很少变动。
问题:业务表往往需要和字典表join查询,当业务表因为规模而进行分片以后,业务表与字典表之间的关联跨库了。
解决:MyCat中通过表冗余来解决这类表的join,即它的定义中指定的dataNode上都有一份该表的拷贝(将字典表或者符合字典表特性的表定义为全局表)
<table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2"/>
4)ER分片关系表:MyCat独有,子表依赖父表,保证在同一个数据库中
MyCat中的ER分片表是基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,保证数据join不会跨库操作。
ER分片是解决跨分片数据join的一种很好的思路,也是数据切分规划的一条重要规则。
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
<childTable name="order_items" joinKey="order_id" parentKey="id"/>
</childTable>
</table>
E-R使用场景:
A表数据量大,访问也很频繁,而且还会有join B表 操作
B表也很大
table primaryKey # A表要分片的字段
childTable joinKey # A和B 表的关联字段
childTable parentKey # 父表的id列
E-R分片示例:
有两个表:
t1:
id name
1 a
2 b
3 c
4 d
t2
id age t1_id
101 12 1
102 14 2
103 11 3
104 15 4
通过MyCAT E-R分片表进行分片后变成,比如分片规则是按t1表id列取模(mod-long)
dataNode sh1:
1 a 101 12 1
3 c 103 11 3
dataNode sh2:
2 b 102 14 2
4 d 104 15 4
- MyCAT基础架构准备
1.1 环境准备:
两台虚拟机 db01 db02
每台创建四个mysql实例:3307 3308 3309 3310
1.2 删除历史环境:
pkill mysqld
\rm -rf /data/330*
\mv /etc/my.cnf /etc/my.cnf.bak
1.3 创建相关目录初始化数据
mkdir /data/33{07..10}/data -p
mysqld --initialize-insecure --user=mysql --datadir=/data/3307/data --basedir=/application/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3308/data --basedir=/application/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3309/data --basedir=/application/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3310/data --basedir=/application/mysql
1.4 准备DB01配置文件和启动脚本
cat >/data/3307/my.cnf<<EOF
[mysqld]
basedir=/application/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=/application/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=/application/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=/application/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=/application/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=/application/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=/application/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=/application/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf
LimitNOFILE = 5000
EOF
1.5 准备DB02配置文件和启动脚本
cat >/data/3307/my.cnf<<EOF
[mysqld]
basedir=/application/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=/application/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=/application/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=/application/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=/application/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=/application/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=/application/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=/application/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf
LimitNOFILE = 5000
EOF
1.6 修改权限,启动多实例
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'"
1.7 节点主从规划
箭头指向谁是主库
10.0.50.61:3306 <-----> 10.0.50.63:3306
10.0.50.61:3307 ------> 10.0.50.61:3306
10.0.50.63:3307 ------> 10.0.50.63:3306
10.0.50.62:3306 <-----> 10.0.50.64:3306
10.0.50.62:3307 -----> 10.0.50.62:3306
10.0.50.64:3307 -----> 10.0.50.64:3306
1.8 分片规划
shard1:
Master:10.0.50.61:3306
slave1:10.0.50.61:3307
Standby Master:10.0.50.63:3306
slave2:10.0.50.63:3307
shard2:
Master:10.0.50.62:3306
slave1:10.0.50.62:3307
Standby Master:10.0.50.64:3306
slave2:10.0.50.64:3307
1.9 开始配置
第一组四节点结构
10.0.50.61:3306 <-----> 10.0.50.63:3306
db03:
mysql -S /tmp/mysql.sock -e "grant replication slave on . to repl@'10.0.50.%' identified by 'repl';"
mysql -S /tmp/mysql.sock -e "grant all on . to root@'10.0.50.%' identified by '123' with grant option;"
db01:
mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.63', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"
db03:
mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.61', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"
=======================
10.0.50.61:3307 ------> 10.0.50.61:3306
db01:
mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.61', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"
10.0.50.63:3307 ------> 10.0.50.63:3306
db03:
mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.63', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"
第二组四节点
10.0.50.62:3306 <-----> 10.0.50.64:3306
db04:
mysql -S /tmp/mysql.sock -e "grant replication slave on . to repl@'10.0.50.%' identified by 'repl';"
mysql -S /tmp/mysql.sock -e "grant all on . to root@'10.0.50.%' identified by '123' with grant option;"
db02:
mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.64', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"
db04:
mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.62', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"
10.0.50.62:3307 -----> 10.0.50.62:3306
db02:
mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.62', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"
10.0.50.64:3307 -----> 10.0.50.64:3306
db04:
mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.64', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"
1.10 检测主从状态
mysql -S /tmp/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/3307/mysql.sock -e "show slave status\G"|grep Yes
==================================================================
注:如果中间出现错误,在每个节点进行执行以下命令,从第1.9步重新开始即可
mysql -S /tmp/mysql.sock -e "stop slave; reset slave all;"
mysql -S /data/3307/mysql.sock -e "stop slave; reset slave all;"
-
MyCAT安装
2.1 预先安装Java运行环境
yum install -y java
2.2下载
Mycat-server-xxxxx.linux.tar.gz
http://dl.mycat.io/
2.3 解压文件
[root@db01 application]# tar xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz
2.4 软件目录结构
ls
bin catlet conf lib logs version.txt
2.5 启动和连接
配置环境变量
vim /etc/profile
export PATH=/application/mycat/bin:$PATH
source /etc/profile
启动
mycat start
连接mycat:
mysql -uroot -p123456 -h 127.0.0.1 -P8066 -
数据库分布式架构方式
3.1 垂直拆分
3.2 水平拆分
range
取模
枚举
hash
时间
等等 -
Mycat基础应用
4.1 主要配置文件介绍
rule.xml *****,分片策略定义
schema.xml *****,主配置文件
server.xml *** ,mycat服务有关
log4j2.xml *** ,记录日志有关
*.txt ,分片策略使用的规则
4.2 用户创建及数据库导入
db01:
mysql -S /data/3307/mysql.sock
grant all on . to root@'10.0.50.%' identified by '123';
source /root/world.sql
mysql -S /data/3308/mysql.sock
grant all on . to root@'10.0.50.%' identified by '123';
source /root/world.sql
4.3 配置文件结构介绍
cd /application/mycat/conf
mv schema.xml schema.xml.bak
vim schema.xml
<mycat:schema xmlns:mycat="http://io.mycat/">
mycat 逻辑库定义:
数据节点定义:
<dataNode name="sh1" dataHost="oldguo1" database= "world" />
==================================================
后端主机定义:
</dataHost>
===================================================
</mycat:schema>
4.4 mycat实现1主1从读写分离
vim schema.xml
<mycat:schema xmlns:mycat="http://io.mycat/">
</mycat:schema>
4.5 Mycat高可用+读写分离
mv schema.xml schema.xml.1
vim schema.xml
<mycat:schema xmlns:mycat="http://io.mycat/">
</mycat:schema>
说明:
第一个 whost: 10.0.50.51:3307 真正的写节点,负责写操作
第二个 whost: 10.0.50.52:3307 准备写节点,负责读,当 10.0.50.51:3307宕掉,会切换为真正的写节点
测试:
[root@db01 conf]# mysql -uroot -p123456 -h 10.0.50.51 -P 8066
读:
mysql> select @@server_id;
写:
mysql> begin ;select @@server_id; commit;
4.6 配置中的属性介绍:
balance属性
负载均衡类型,目前的取值有3种:
- balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
- balance="1",全部的readHost与standby writeHost参与select语句的负载均衡,简单的说,
当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。 - balance="2",所有读操作都随机的在writeHost、readhost上分发。
writeType属性
负载均衡类型,目前的取值有2种:
- writeType="0", 所有写操作发送到配置的第一个writeHost,
第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为主,切换记录在配置文件中:dnindex.properties . - 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时
- Mycat高级应用-分布式解决方案
5.1 垂直分表
mv schema.xml schema.xml.ha
vim schema.xml
<mycat:schema xmlns:mycat="http://io.mycat/">
<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.50.51:3308" user="root" password="123">
<readHost host="db2" url="10.0.50.51:3310" user="root" password="123" />
</writeHost>
<writeHost host="db3" url="10.0.50.52:3308" user="root" password="123">
<readHost host="db4" url="10.0.50.52:3310" user="root" password="123" />
</writeHost>
</dataHost>
</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 :
mycat restart
测试功能:
[root@db01 conf]# mysql -uroot -p123456 -h 10.0.50.51 -P 8066
mysql> use TESTDB
mysql> insert into user(id ,name ) values(1,'a'),(2,'b');
mysql> commit;
mysql> insert into order_t(id ,name ) values(1,'a'),(2,'b');
mysql> commit;
[root@db01 ~]# mysql -S /data/3307/mysql.sock -e "show tables from taobao;"
+------------------+
| Tables_in_taobao |
+------------------+
| user |
+------------------+
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show tables from taobao;"
+------------------+
| Tables_in_taobao |
+------------------+
| order_t |
+------------------+
[root@db01 ~]#
5.2 Mycat分布式-水平拆分(分片)介绍
分片:对一个"bigtable",比如说t3表
(1)行数非常多,800w
(2)访问非常频繁
分片的目的:
(1)将大数据量进行分布存储
(2)提供均衡的访问路由
分片策略:
范围 range 800w 1-400w 400w01-800w
取模 mod 取余数
枚举
哈希 hash
时间 流水
优化关联查询
全局表
ER分片
5.3 Mycat分布式-范围分片
比如说t3表
(1)行数非常多,2000w(1-1000w:sh1 1000w01-2000w:sh2)
(2)访问非常频繁,用户访问较离散
cp schema.xml schema.xml.11
vim schema.xml
vim rule.xml
vim autopartition-long.txt
1-10=0 -----> >=1 , <=10
10-20=1 -----> >10 ,<=20
创建测试表:
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(10,'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');
insert into t3(id,name) values(20,'dd');
5.4 取模分片(mod-long):
取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点
vim schema.xml
vim rule.xml
准备测试环境
创建测试表:
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.50.51 -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 -e "select * from taobao.t4;"
mysql -S /data/3308/mysql.sock -e "select * from taobao.t4;"
- 枚举分片
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
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.50.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');
分别登录后端节点查询数据
mysql -S /data/3307/mysql.sock -e "select * from taobao.t5;"
mysql -S /data/3308/mysql.sock -e "select * from taobao.t5;"
======================================
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性