文章目录
- 使用 MyCat 实现 MySQL 主从读写分离完整指南
- 一、MySQL 读写分离基础概述
- 1.1 读写分离工作原理
- 1.2 为什么需要读写分离
- 1.3 读写分离的两种实现方式
- 主流读写分离中间件对比
- 二、MyCat 中间件简介
- 2.1 MyCat 核心功能
- 2.2 MyCat 适用场景
- 三、环境准备与 MyCat 安装
- 3.1 前提:安装 JDK(mycat服务器192.168.100.200)
- 3.2 MyCat 下载与解压
- 3.3 创建 MyCat 专用用户与权限配置
- 3.4 MyCat 目录结构说明
- 四、MyCat 核心配置(读写分离关键)
- 4.1 配置 MyCat 环境变量
- 4.2 配置用户授权(server.xml)
- 4.3 配置逻辑库与主从路由(schema.xml)
- 4.3.1 配置模板(适配“1主2从”架构)
- 4.3.2 核心参数详解(读写分离关键)
- 五、MySQL 主从复制配置(读写分离前提)
- 5.1 前提:主从库环境准备
- 5.2 主库(Master)配置
- 5.3 从库(Slave1/Slave2)配置
- 六、MyCat 启动与读写分离测试
- 6.1 启动 MyCat
- 6.2 读写分离测试
- 6.2.1 测试读操作(仅从库接收,从库负载均衡)
- 6.2.2 测试写操作(仅主库接收)
- 六、总结
使用 MyCat 实现 MySQL 主从读写分离完整指南
一、MySQL 读写分离基础概述
在高并发业务场景中,单台 MySQL 数据库难以同时承载大量读写请求。读写分离通过“主库写、从库读”的分工,结合主从复制保障数据一致性,成为缓解数据库压力的核心方案。
1.1 读写分离工作原理
读写分离的核心是“请求路由”与“数据同步”的结合,具体流程如下:
- 角色分工:
- 主库(Master):仅处理写操作(INSERT/UPDATE/DELETE/DDL),确保数据变更的唯一性和一致性;
- 从库(Slave):仅处理读操作(SELECT),分担主库的读请求压力(如商品查询、数据统计)。
- 数据同步:依赖 MySQL 主从复制机制——主库将写操作记录到“二进制日志(Binary Log)”,从库通过 IO 线程拉取日志并写入“中继日志(Relay Log)”,再通过 SQL 线程回放日志,实现与主库数据同步。
- 路由转发:通过中间件(如 MyCat)或应用层判断请求类型,自动将写请求转发到主库,读请求分发到从库(支持负载均衡)。
1.2 为什么需要读写分离
- 突破单库性能瓶颈:多数业务中读请求占比超 80%(如电商详情页、新闻列表),将读请求分流到从库,可显著降低主库负载;
- 缓解锁争用:写操作会加排他锁(X 锁),读操作加共享锁(S 锁),分离后避免“写锁阻塞读、读锁阻塞写”的问题;
- 优化读性能:从库可针对性优化(如启用查询缓存、使用 MyISAM 引擎),进一步提升读响应速度;
- 提高可用性:主库故障时,从库可切换为新主库,减少业务中断时间(需配合故障切换机制)。
1.3 读写分离的两种实现方式
读写分离主要通过“应用层”或“中间件层”实现,MyCat 属于中间件层方案,两种方式对比如下:
实现方式 | 核心逻辑 | 优点 | 缺点 |
---|---|---|---|
应用程序层实现 | 在代码中判断 SQL 类型(写请求→主库,读请求→从库),直接连接数据库 | 无中间件开销,性能损耗低;部署简单 | 代码耦合度高,多语言应用需重复开发;架构调整(如增减从库)需修改代码 |
中间件层实现 | 在客户端与数据库间部署代理(如 MyCat),由代理统一解析请求、转发路由 | 对应用透明(无需改代码);支持分库分表、故障切换、负载均衡 | 增加系统复杂度;代理层需优化配置以避免成为新瓶颈 |
主流读写分离中间件对比
中间件 | 开发背景 | 支持事务 | 支持存储过程 | 核心优势 | 适用场景 |
---|---|---|---|---|---|
MyCat | 开源社区(基于 Cobar 二次开发) | 支持 | 支持 | 社区活跃、功能全面(读写分离+分库分表)、文档丰富 | 中小到大型企业,需灵活扩展的场景 |
Cobar | 阿里巴巴 B2B 团队 | 支持 | 支持 | 早期成熟方案,稳定性强 | 已停更,仅适合维护 legacy 系统 |
OneProxy | 商业软件 | 支持 | 支持 | 高并发稳定性好,提供商业支持 | 对稳定性要求高的付费场景 |
Amoeba | 阿里陈思儒(个人开发) | 不支持 | 不支持 | 轻量易用,部署简单 | 小型读密集场景,无复杂事务需求 |
二、MyCat 中间件简介
MyCat 是开源企业级数据库中间件,定位为“MySQL 集群的统一入口”,通过封装底层数据库拓扑,为应用提供透明的“逻辑库”访问方式,核心能力聚焦于读写分离与分库分表。
2.1 MyCat 核心功能
- 读写分离:自动路由写请求到主库、读请求到从库,支持多种读负载均衡策略;
- 分库分表:将大表按规则(如哈希、范围)拆分到多个数据库,解决单库数据量过大问题;
- 事务支持:兼容 MySQL 事务特性,保障 ACID 一致性;
- 高可用:支持主从故障自动切换,减少人工干预;
- 扩展性:可融合内存缓存、NoSQL、HDFS 等技术,适配复杂数据场景。
2.2 MyCat 适用场景
- 读请求密集的业务(如电商、新闻、社交);
- 数据量较大,需分库分表扩展的场景;
- 多语言应用或微服务架构,需统一数据库访问入口;
- 需降低应用与数据库耦合度,简化架构调整的场景。
三、环境准备与 MyCat 安装
MyCat 基于 Java 开发,需先配置 JDK 环境,再完成安装与目录初始化(以 CentOS 7.9、MyCat 1.6 为例)。
1.整个实验的环境 以及服务器信息
- 环境部署:CentOS 7.9
- 虚拟机服务环境:
- Master服务器:192.168.100.129,部署 mysql 5.7
- Slave1服务器:192.168.100.140,部署 mysql 5.7
- Slave2服务器:192.168.100.150,部署 mysql 5.7
- MyCat服务器:192.168.100.200(预备机器),部署 jdk-8u191-linux + MyCat中间件
2.先完成master,slave1,slave2的主从复制配置,详情请见
3.1 前提:安装 JDK(mycat服务器192.168.100.200)
MyCat 依赖 Java 运行环境,推荐 JDK 1.8,linux自带的open jdk 1.8也行。
- 下载并解压 JDK:
# 下载 JDK 1.8(可从 Oracle 官网或国内镜像获取) wget https://repo.huaweicloud.com/java/jdk/8u191-b12/jdk-8u191-linux-x64.tar.gz # 解压到 /usr/java 目录 mkdir -p /usr/java tar -zxvf jdk-8u191-linux-x64.tar.gz -C /usr/java/
- 配置 JDK 环境变量:
vim /etc/profile.d/java.sh # 添加以下内容 export JAVA_HOME=/usr/java/jdk1.8.0_191 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar # 生效环境变量 source /etc/profile.d/java.sh # 验证安装(显示 JDK 版本即成功) java -version
3.2 MyCat 下载与解压
- 下载 MyCat 稳定版(1.6 RELEASE):
# 从 GitHub 下载(或访问 MyCat 官网:http://www.mycat.org.cn/) wget https://github.com/MyCATApache/Mycat-download/blob/master/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gzrz #本地上传mycat压缩包(推荐)
- 解压到 /usr/local 目录:
tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/ # 进入 MyCat 目录,确认结构 cd /usr/local/mycat ls # 应显示 bin、conf、lib、logs 等目录
3.3 创建 MyCat 专用用户与权限配置
为避免使用 root 运行中间件,创建专用用户并授权:
# 创建 mycat 用户
useradd mycat
# 设置密码(123)
passwd mycat #密码为123
# 授权 MyCat 目录权限给 mycat 用户
chown -R mycat.mycat /usr/local/mycat
3.4 MyCat 目录结构说明
目录路径 | 核心作用 |
---|---|
/usr/local/mycat/bin | 可执行文件:mycat(启动/停止/重启脚本)、wrapper(底层启动依赖) |
/usr/local/mycat/conf | 配置文件:server.xml(用户授权)、schema.xml(逻辑库与路由)、rule.xml(分片规则) |
/usr/local/mycat/lib | 依赖 JAR 包:MySQL 驱动、MyCat 核心组件等 |
/usr/local/mycat/logs | 日志文件:wrapper.log(启动日志,排查启动故障)、mycat.log(业务日志) |
四、MyCat 核心配置(读写分离关键)
MyCat 实现读写分离的核心是“定义逻辑库→绑定数据节点→配置主从路由”,关键配置文件为 server.xml
(用户授权)和 schema.xml
(路由规则)。
4.1 配置 MyCat 环境变量
为方便全局调用 MyCat 命令,配置环境变量:
vim /etc/profile.d/mycat.sh
# 添加以下内容
export MYCAT_HOME=/usr/local/mycat
export PATH=$MYCAT_HOME/bin:$PATH
# 生效环境变量
source /etc/profile.d/mycat.sh
4.2 配置用户授权(server.xml)
定义客户端访问 MyCat 的账号、密码及关联的“逻辑库”(逻辑库是 MyCat 封装的虚拟库,对应底层物理库):
vim /usr/local/mycat/conf/server.xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/"><!-- 管理员账号:拥有读写权限 --><user name="mycat"><property name="password">123</property> <!-- 密码 --><property name="schemas">ceshi</property> <!-- 关联逻辑库名称(需与 schema.xml 一致),必须是关联的主从库里的库。 --></user><!-- 普通用户:仅只读权限 --><user name="user"><property name="password">user</property><property name="schemas">ceshi</property><property name="readOnly">true</property> <!-- 只读配置,禁止写操作 --></user>
</mycat:server>
4.3 配置逻辑库与主从路由(schema.xml)
schema.xml
是读写分离的核心配置文件,需定义“逻辑库→数据节点→主从数据库”的映射关系,并指定读写策略。
4.3.1 配置模板(适配“1主2从”架构)
1.首先进行源文件备份
mv /usr/local/mycat/conf/schema.xml /usr/local/mycat/conf/schema.xml.bak
vim /usr/local/mycat/conf/schema.xml
下方内容直接复制粘贴,ip改为自己的机器即可。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><schema name="ceshi" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema><dataNode name="dn1" dataHost="dthost" database="ceshi"/> <dataHost name="dthost"maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select 1</heartbeat><writeHost host="master" url="192.168.100.139:3306" user="mycat" password="123"> <readHost host="slave1" url="192.168.100.128:3306" user="mycat"password="123"/><readHost host="slave2" url="192.168.100.130:3306" user="mycat"password="123"/></writeHost></dataHost>
</mycat:schema>
4.3.2 核心参数详解(读写分离关键)
参数名 | 取值与含义 | 推荐配置 |
---|---|---|
balance | 读负载均衡策略: - 0:不分离,所有读请求走写节点; - 1:所有从库+备用主库参与读负载; - 2:读请求随机分发到主库+从库; - 3:读请求仅走从库,主库不承担读 | 1(均衡分担读压力) |
writeType | 写策略: - 0:所有写请求走第一个 writeHost(主库); - 1:写请求随机走 writeHost(1.5+ 已废弃) | 0(主库唯一写节点) |
switchType | 主从切换策略: - -1:不自动切换,需手动干预; - 1:默认自动切换(基于心跳检测); - 2:基于主从同步状态切换(心跳用 show slave status); - 3:基于 MySQL MGR 集群切换 | -1(手动切换更安全,避免误切) |
五、MySQL 主从复制配置(读写分离前提)
MyCat 读写分离依赖 MySQL 主从复制(确保从库数据与主库一致),需先完成“1主2从”的主从配置(以 MySQL 5.7 为例)。
5.1 前提:主从库环境准备
- 主库(Master):IP 192.168.100.129,已安装 MySQL 5.7;
- 从库1(Slave1):IP 192.168.100.140,已安装 MySQL 5.7;
- 从库2(Slave2):IP 192.168.100.150,已安装 MySQL 5.7;
- 所有节点关闭防火墙与 SELinux:
主从复制详情见主从复制systemctl stop firewalld && systemctl disable firewalld setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
5.2 主库(Master)配置
以下均为主从复制配置完成后的设置:
mysql> create database ceshi;
mysql> use database;
mysql> create table test (id int(10),name varchar(10),address varchar(20));mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123';
mysql> flush privileges;
5.3 从库(Slave1/Slave2)配置
以下均为主从复制配置完成后的设置:
mysql> grant all on db.* to 'mycat'@'%' identified by '123';
六、MyCat 启动与读写分离测试
完成 MyCat 与 MySQL 主从配置后,启动 MyCat 并验证读写分离效果。
6.1 启动 MyCat
- 启动 MyCat:
cd /usr/local/mycat/bin ./mycat start # 启动;停止用 mycat stop,重启用 mycat restart
- 验证启动状态:
# 查看 MyCat 进程(默认端口 8066,管理端口 9066) netstat -tnlp | grep 8066 ./mycat status #显示running即可。 # 查看启动日志(排查故障,如端口占用、配置错误) cat /usr/local/mycat/logs/wrapper.log(可不查)
6.2 读写分离测试
测试需通过“客户端连接 MyCat”而非直接连接 MySQL,验证“写走主库、读走从库”。
6.2.1 测试读操作(仅从库接收,从库负载均衡)
在测试读实验期间,后台的主从复制必须正常启动,不能关闭
-
客户端连接 MyCat(在第四台机器192.168.100.200):
yum install -y mariadb-server mariadb #mycat只是中间件,需要借助客户端工具才能提供数据交互终端。 systemctl start mariadb.service
-
切换到master库ceshi,插入数据:
mysql> use ceshi;# 插入数据 mysql> insert into test values('3','wangwu','this_is_master');
-
slave1从属机
mysql> use ceshi; mysql> insert into test values('1','zhangsan','this_is_slave1'); mysql> select * from test
-
slave2从属机
mysql> use ceshi; mysql> insert into test values('2','lisi','this_is_slave2'); mysql> select * from test
-
在mycat机器上
#格式:mysql -uMyCat账号 -p密码 -hMyCatIP -PMyCat端口(默认 8066) mysql -umycat -p123 -h127.0.0.1 -P8066 # MyCat 部署在 192.168.100.200 mysql> show databases; #显示ceshi库 mysql> use ceshi; mysql> show tables; #显示test表 mysql> select * from test; #交替显示slave1,slave2的表,即为成功。
-
观察结果
在 MyCat 客户端(192.168.100.200 机器)多次执行 select * from test; 后,可观察到以下核心现象:
- 数据来源仅为从库:执行查询时,始终不会出现主库(master)中插入的记录 (‘3’,‘wangwu’,‘this_is_master’),证明读操作未路由到主库,仅从从库获取数据;
- 从库负载均衡生效:多次执行查询会交替返回两个从库的独有数据:
交替出现的结果表明 MyCat 已实现从库间的读请求负载均衡,符合 “读走从库” 的读写分离预期。
6.2.2 测试写操作(仅主库接收)
- 暂停从库主从同步(仅测试用,模拟从库数据差异):
- 连接 Slave1(192.168.100.140):
mysql> stop slave; #防止主机的数据被同步到从属机。
- 连接 Slave2(192.168.100.150):
mysql> stop slave; #防止主机的数据被同步到从属机。
- 连接 Slave1(192.168.100.140):
- MyCat服务器,执行写操作:
mysql> insert into test values('4','qianqi','this_is_client');
- 观察结果:
在 MyCat 客户端执行 insert into test values(‘4’,‘qianqi’,‘this_is_client’); 后,分别登录主库(master)、slave1、slave2 查看 test 表,可观察到以下对比现象:
- 主库(master)数据变化:
登录主库执行 select * from ceshi.test;,能看到新增记录 (‘4’,‘qianqi’,‘this_is_client’),同时保留主库原有记录 (‘3’,‘wangwu’,‘this_is_master’),证明写操作已路由到主库;
从库(slave1、slave2)数据无变化:
结合 “已暂停主从同步” 的前提,从库未出现新增数据,直接证明写操作未路由到任何从库,仅主库接收写请求,符合 “写走主库” 的读写分离预期。
六、总结
- 核心依赖:MyCat 读写分离的前提是 MySQL 主从复制,需确保从库
Slave_IO_Running
与Slave_SQL_Running
均为Yes
; - 关键配置:MyCat 的
schema.xml
中,balance
(读负载)、writeType
(写路由)、switchType
(故障切换)是决定读写分离效果的核心参数; - 价值:MyCat 为应用提供透明的数据库访问入口,无需修改代码即可实现读写分离,同时支持扩展分库分表,是企业级 MySQL 架构的重要中间件;
- 注意事项:生产环境需关闭
validate-password=OFF
,配置强密码;switchType
建议设为 -1(手动切换),避免主从延迟导致的切换异常;定期监控主从延迟与 MyCat 连接池状态。