Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MyCat实现MySQL主从读写分离

使用MyCat实现MySQL主从读写分离全过程

作者:matlab的学徒

本文介绍MySQL读写分离原理及实现方式,重点讲解MyCat中间件的配置与使用,涵盖主从复制、逻辑库路由、负载均衡等,旨在提升高并发场景下数据库性能,降低应用与数据库耦合度,适用于企业级架构优化

一、MySQL 读写分离基础概述

在高并发业务场景中,单台 MySQL 数据库难以同时承载大量读写请求。读写分离通过“主库写、从库读”的分工,结合主从复制保障数据一致性,成为缓解数据库压力的核心方案。

1.1 读写分离工作原理

读写分离的核心是“请求路由”与“数据同步”的结合,具体流程如下:

角色分工

数据同步:依赖 MySQL 主从复制机制——主库将写操作记录到“二进制日志(Binary Log)”,从库通过 IO 线程拉取日志并写入“中继日志(Relay Log)”,再通过 SQL 线程回放日志,实现与主库数据同步。

路由转发:通过中间件(如 MyCat)或应用层判断请求类型,自动将写请求转发到主库,读请求分发到从库(支持负载均衡)。

1.2 为什么需要读写分离

  1. 突破单库性能瓶颈:多数业务中读请求占比超 80%(如电商详情页、新闻列表),将读请求分流到从库,可显著降低主库负载;
  2. 缓解锁争用:写操作会加排他锁(X 锁),读操作加共享锁(S 锁),分离后避免“写锁阻塞读、读锁阻塞写”的问题;
  3. 优化读性能:从库可针对性优化(如启用查询缓存、使用 MyISAM 引擎),进一步提升读响应速度;
  4. 提高可用性:主库故障时,从库可切换为新主库,减少业务中断时间(需配合故障切换机制)。

1.3 读写分离的两种实现方式

读写分离主要通过“应用层”或“中间件层”实现,MyCat 属于中间件层方案,两种方式对比如下:

实现方式核心逻辑优点缺点
应用程序层实现在代码中判断 SQL 类型(写请求→主库,读请求→从库),直接连接数据库无中间件开销,性能损耗低;部署简单代码耦合度高,多语言应用需重复开发;架构调整(如增减从库)需修改代码
中间件层实现在客户端与数据库间部署代理(如 MyCat),由代理统一解析请求、转发路由对应用透明(无需改代码);支持分库分表、故障切换、负载均衡增加系统复杂度;代理层需优化配置以避免成为新瓶颈
主流读写分离中间件对比
中间件开发背景支持事务支持存储过程核心优势适用场景
MyCat开源社区(基于 Cobar 二次开发)支持支持社区活跃、功能全面(读写分离+分库分表)、文档丰富中小到大型企业,需灵活扩展的场景
Cobar阿里巴巴 B2B 团队支持支持早期成熟方案,稳定性强已停更,仅适合维护 legacy 系统
OneProxy商业软件支持支持高并发稳定性好,提供商业支持对稳定性要求高的付费场景
Amoeba阿里陈思儒(个人开发)不支持不支持轻量易用,部署简单小型读密集场景,无复杂事务需求

二、MyCat 中间件简介

MyCat 是开源企业级数据库中间件,定位为“MySQL 集群的统一入口”,通过封装底层数据库拓扑,为应用提供透明的“逻辑库”访问方式,核心能力聚焦于读写分离与分库分表。

2.1 MyCat 核心功能

  1. 读写分离:自动路由写请求到主库、读请求到从库,支持多种读负载均衡策略;
  2. 分库分表:将大表按规则(如哈希、范围)拆分到多个数据库,解决单库数据量过大问题;
  3. 事务支持:兼容 MySQL 事务特性,保障 ACID 一致性;
  4. 高可用:支持主从故障自动切换,减少人工干预;
  5. 扩展性:可融合内存缓存、NoSQL、HDFS 等技术,适配复杂数据场景。

2.2 MyCat 适用场景

三、环境准备与 MyCat 安装

MyCat 基于 Java 开发,需先配置 JDK 环境,再完成安装与目录初始化(以 CentOS 7.9、MyCat 1.6 为例)。 

1.整个实验的环境 以及服务器信息

虚拟机服务环境:

2.先完成master,slave1,slave2的主从复制配置,详情请见

3.1 前提:安装 JDK(mycat服务器192.168.100.200)

MyCat 依赖 Java 运行环境,推荐 JDK 1.8,linux自带的open jdk 1.8也行。

# 下载 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/
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 下载与解压

# 从 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.gz

rz    #本地上传mycat压缩包(推荐)
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 前提:主从库环境准备

所有节点关闭防火墙与 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 测试读操作(仅从库接收,从库负载均衡)

在测试读实验期间,后台的主从复制必须正常启动,不能关闭

yum install -y mariadb-server mariadb      #mycat只是中间件,需要借助客户端工具才能提供数据交互终端。
systemctl start mariadb.service 
mysql> use ceshi;

# 插入数据
mysql> insert into test values('3','wangwu','this_is_master');
mysql> use ceshi;
mysql> insert into test values('1','zhangsan','this_is_slave1');
mysql> select * from test
mysql> use ceshi;
mysql> insert into test values('2','lisi','this_is_slave2');
mysql> select * from test
#格式: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; 后,可观察到以下核心现象:

6.2.2 测试写操作(仅主库接收)
  1. 暂停从库主从同步(仅测试用,模拟从库数据差异):

连接 Slave1(192.168.100.140):

mysql> stop slave;  #防止主机的数据被同步到从属机。

连接 Slave2(192.168.100.150):

mysql> stop slave;  #防止主机的数据被同步到从属机。

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)数据变化

结合 “已暂停主从同步” 的前提,从库未出现新增数据,直接证明写操作未路由到任何从库,仅主库接收写请求,符合 “写走主库” 的读写分离预期。

六、总结

  1. 核心依赖:MyCat 读写分离的前提是 MySQL 主从复制,需确保从库 Slave_IO_RunningSlave_SQL_Running 均为 Yes
  2. 关键配置:MyCat 的 schema.xml 中,balance(读负载)、writeType(写路由)、switchType(故障切换)是决定读写分离效果的核心参数;
  3. 价值:MyCat 为应用提供透明的数据库访问入口,无需修改代码即可实现读写分离,同时支持扩展分库分表,是企业级 MySQL 架构的重要中间件;
  4. 注意事项:生产环境需关闭 validate-password=OFF,配置强密码;switchType 建议设为 -1(手动切换),避免主从延迟导致的切换异常;定期监控主从延迟与 MyCat 连接池状态。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文