前言
读写分离本身是没有主从复制的,我们要配置主从复制后再配置读写分离。
现在常见的两种方式
- MyCat
- MySQL Router
MyCat
是优化而来,支持半自动化分片,join。为什么叫”半自动化”呢?因为需要DBA对每个表的分片策略进行配置和干涉。
MySQL Router
MySQL Proxy 和 MySQL Router 是官方提供的两个玩具,不推荐使用。
MySQL Proxy:应用程序连接 MySQL Proxy 后,MySQL Proxy 会自动将写请求和读请求分离,分别发送给 Master 和 Slave。但是官方不建议在生产环境使用 MySQL Proxy。
MySQL Router:是 MySQL Proxy 的替代方案。但是 MySQL Router 启动后,包含读端口和写端口,因此就需要应用程序自己将读和写进行分离,分别发送到 MySQL Router 相应的端口上。应用程序需要额外将读写操作进行分流,麻烦。
MyCat文档
MyCat已经废弃,新的为Mycat 2
http://mycatone.top/
https://github.com/MyCATApache/Mycat2
文档:
https://www.yuque.com/ccazhw/ml3nkf/ob0u6a
JDK
官方下载JDK 网址
链接: https://pan.baidu.com/s/1COHU0dKhBb9x_wWxIwuibw 提取码: psvm
安装
代码语言:javascript复制sudo tar -zxvf jdk-8u341-linux-x64.tar.gz -C /usr/local
安装后的路径为/usr/local/jdk1.8.0_341
cd /etc/profile.d/
创建配置文件
代码语言:javascript复制sudo vi /etc/profile.d/jdk.sh
加入:
代码语言:javascript复制export JAVA_HOME=/usr/local/jdk1.8.0_341
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
配置立即生效
代码语言:javascript复制source /etc/profile
查询java版本
代码语言:javascript复制java -version
查看java-home
代码语言:javascript复制echo $JAVA_HOME
MyCat下载
MyCat是基于Java开发的,要安装JDK。
代码语言:javascript复制wget http://dl.mycat.org.cn/2.0/install-template/mycat2-install-template-1.21.zip
wget http://dl.mycat.org.cn/2.0/1.21-release/mycat2-1.21-release-jar-with-dependencies.jar
百度云下载
链接:https://pan.baidu.com/s/1bgYByp0Gyv0z-xHIxrsdbg 提取码:psvm
MyCat安装
创建目录
代码语言:javascript复制mkdir -p /data/tools/
解压
代码语言:javascript复制unzip mycat2-install-template-1.21.zip -d /data/tools/
cp mycat2-1.21-release-jar-with-dependencies.jar /data/tools/mycat/lib/
查看是否成功
代码语言:javascript复制cd /data/tools/mycat/lib/
添加权限
代码语言:javascript复制cd /data/tools/mycat/bin
chmod x *
服务配置
以下的配置服务只用配置一次就行。
修改 Mycat 登录用户信息
代码语言:javascript复制vi /data/tools/mycat/conf/users/root.user.json
内容如下:
代码语言:javascript复制{
"dialect":"mysql",
"ip":null,
"password":"123456",
"transactionType":"xa",
"username":"root"
}
只需要修改用户名密码,别的不用更改。
修改 Mycat 服务
代码语言:javascript复制cd /data/tools/mycat/conf/
vi server.json
内容
代码语言:javascript复制{
"loadBalance":{
"defaultLoadBalance":"BalanceRandom",
"loadBalances":[]
},
"mode":"local",
"properties":{},
"server":{
"bufferPool":{
},
"idleTimer":{
"initialDelay":3,
"period":60000,
"timeUnit":"SECONDS"
},
"ip":"0.0.0.0",
"mycatId":1,
"port":8066,
"serverVersion":"5.7.39-mycat-2.0",
"reactorNumber":8,
"tempDirectory":null,
"timeWorkerPool":{
"corePoolSize":0,
"keepAliveTime":1,
"maxPendingLimit":65535,
"maxPoolSize":2,
"taskTimeout":5,
"timeUnit":"MINUTES"
},
"workerPool":{
"corePoolSize":1,
"keepAliveTime":1,
"maxPendingLimit":65535,
"maxPoolSize":1024,
"taskTimeout":5,
"timeUnit":"MINUTES"
}
}
}
主要添加了serverVersion
配置
serverVersion
中前面是MySQL的版本后面是Mycat的版本
查看Mysql的版本
代码语言:javascript复制select version();
mycatId
是保证多个mycat公用存储节点的时候必须配置这个值,并且唯一,他用于生成序列号,Xid等.
原型库连接
只用设置一次。
在主节点创建 Mycat 使用的数据库 mycat
CREATE DATABASE IF NOT EXISTS mycat;
这个库称为 Mycat 的原型库(prototype),Mycat 在启动时,会自动在原型库下创建其运行时所需的数据表。
代码语言:javascript复制cd /data/tools/mycat/conf/datasources
把mycat带的数据源配置正确
修改配置文件
代码语言:javascript复制vi prototypeDs.datasource.json
内容如下
代码语言:javascript复制{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ_WRITE",
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"prototypeDs",
"password":"123456",
"type":"JDBC",
"url":"jdbc:mysql://localhost:3306/mycat?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
"user":"root",
"weight":0
}
主要修改
代码语言:javascript复制"password":"123456",
"url":"jdbc:mysql://localhost:3306/mycat?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
"user":"root",
主从配置
主从库添加
代码语言:javascript复制CREATE DATABASE IF NOT EXISTS zdb;
use zdb;
CREATE TABLE IF NOT EXISTS `t_user`(
`userid` INT UNSIGNED AUTO_INCREMENT,
`username` VARCHAR(100) NOT NULL,
`password` VARCHAR(40) NOT NULL,
`createtime` DATETIME,
PRIMARY KEY ( `userid` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO t_user (username, password,createtime) VALUES ( "zhangsan", "123456",now());
主从连接
这里用到的数据库
mycat
Mycat使用的原型库zdb
主库zdb
从库
主库连接
新添加其他配置,
代码语言:javascript复制cd /data/tools/mycat/conf/datasources
cp prototypeDs.datasource.json zdb-master.datasource.json
vi zdb-master.datasource.json
内容如下
代码语言:javascript复制{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ_WRITE",
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"zdb-master",
"password":"123456",
"type":"JDBC",
"url":"jdbc:mysql://localhost:3306/zdb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
"user":"root",
"weight":0
}
注意修改其中的
- instanceType
- name
- user
- password
- url
从库连接
编辑
代码语言:javascript复制cp zdb-master.datasource.json zdb-slave-01.datasource.json
vi zdb-slave-01.datasource.json
内容
代码语言:javascript复制{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
// 数据库读写类型。在数据库集群时,Mycat 对从节点都是只读的
"instanceType":"READ",
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
// 数据源名称。在后面配置数据库集群时会用到
"name":"zdb-slave-01",
// 数据库密码
"password":"123456",
"type":"JDBC",
// 从节点数据库连接
"url":"jdbc:mysql://172.17.0.3:3306/zdb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
// 数据库用户
"user":"root",
"weight":0
}
注意修改其中的
- instanceType
- name
- user
- password
- url
配置集群信息
代码语言:javascript复制cd /data/tools/mycat/conf/clusters
# 注意:这里不要删除 prototype.cluster.json,否则启动 Mycat 时会报错
cp prototype.cluster.json zdb.cluster.json
vi zdb.cluster.json
内容
代码语言:javascript复制{
// 集群类型:SINGLE_NODE(单节点)、MASTER_SLAVE(普通主从)、GARELA_CLUSTER(garela cluster/PXC集群)等
"clusterType":"MASTER_SLAVE",
"heartbeat":{
"heartbeatTimeout":1000,
"maxRetry":3,
"minSwitchTimeInterval":300,
"slaveThreshold":0
},
"masters":[
// 主节点数据源名称
"zdb-master"
],
"replicas":[
// 从节点数据源名称
"zdb-slave-01"
],
"maxCon":200,
// 集群名称。在后面配置schema时会用到
"name":"zdb-slave",
"readBalanceType":"BALANCE_ALL",
// NOT_SWITCH(不进行主从切换)、SWITCH(进行主从切换)
"switchType":"NOT_SWITCH"
}
配置Schema
配置物理库(schema)和 Mycat 中数据源/数据源集群的关系
代码语言:javascript复制cd /data/tools/mycat/conf/schemas
vi zdb.schema.json
内容
代码语言:javascript复制{
"schemaName": "zdb",
"targetName": "zdb-slave",
"normalTables": {}
}
其中
- schemaName schema名称 可以随便配置。
- targetName 上面配置的集群的名称。
- normalTables 这里可以配置数据表相关的信息,在物理表已存在或需要启动时自动创建物理表时配置此项。
启动Mycat
代码语言:javascript复制cd /data/tools/mycat/bin/
./mycat start
查看Mycat日志
代码语言:javascript复制cd /data/tools/mycat/logs
cat wrapper.log
连接MyCat
代码语言:javascript复制mysql -uroot -p -h127.0.0.1 -P8066
注意端口号是Mycat端口号8066
验证读写分离
在主从节点均开启日志记录
代码语言:javascript复制# 把日志输出到表;开启日志记录
SET GLOBAL log_output = 'TABLE'; SET GLOBAL general_log = 'ON';
# 清空 mysql.general_log 日志表中的记录
TRUNCATE TABLE mysql.general_log;
在 Mycat 中分别执行插入和查询语句
代码语言:javascript复制show databases;
use zdb;
INSERT INTO t_user (username, password,createtime) VALUES ( "lisi", "123456",now());
SELECT * FROM t_user;
分别在主从节点执行如下语句,查询 SQL 执行历史
代码语言:javascript复制-- 可以看到主节点上有一条 INSERT 和一条 SELECT;从节点上只有一条 SELECT
SELECT event_time,
user_host,
thread_id,
server_id,
command_type,
CAST(argument AS CHAR(500) CHARACTER SET utf8mb4) argument
FROM mysql.general_log
ORDER BY event_time DESC;
在主从节点关闭日志记录
代码语言:javascript复制# 把日志输出到文件(默认设置);关闭日志记录
SET GLOBAL log_output = 'FILE'; SET GLOBAL general_log = 'OFF';