Mycat 读写分离配置实战(CentOS 环境)
Mycat 读写分离的核心逻辑是:写请求(INSERT/UPDATE/DELETE)转发到主库(writeHost),读请求(SELECT)转发到从库(readHost),应用无需修改代码,仅需通过 Mycat 配置实现流量分发,从而提升系统并发能力。
以下基于之前的 Mycat 入门环境,详细讲解「一主一从」架构的读写分离配置(最常用场景),包含「主从复制准备→Mycat 配置→验证效果」全流程。
一、前置条件(必做)
1. 环境准备
- 已安装 Mycat(1.6.x 稳定版,之前入门环境可直接复用)。
- 2 台 MySQL 服务器(CentOS 系统),需先搭建 MySQL 主从复制(Mycat 不负责数据同步,仅负责请求转发,数据一致性依赖 MySQL 自身主从复制):
- 主库(Master):
192.168.1.101:3306,数据库db1(已创建)。 - 从库(Slave):
192.168.1.103:3306,数据库db1(需手动创建,与主库一致)。
- 主库(Master):
- 所有数据库已创建 Mycat 连接用户(
mycat/123456),并授予权限:sql-- 主库、从库都执行(允许 Mycat 连接) GRANT ALL ON *.* TO 'mycat'@'%' IDENTIFIED BY '123456'; FLUSH PRIVILEGES;
2. 关键前提:搭建 MySQL 主从复制
Mycat 读写分离的基础是「主从数据一致」,需先完成 MySQL 主从复制配置(以 MySQL 8.0 为例):
步骤 1:配置主库(192.168.1.101)
- 编辑 MySQL 配置文件:
bash运行
vim /etc/my.cnf # 或 /etc/my.cnf.d/mysql-server.cnf(CentOS 8+) - 添加以下配置(开启二进制日志,指定主库 ID):
ini
[mysqld] server-id = 101 # 唯一 ID(1-2^32-1,不能与从库重复) log-bin = mysql-bin # 开启二进制日志(主从复制依赖) binlog-do-db = db1 # 仅同步 db1 数据库(按需配置,不写则同步所有库) - 重启 MySQL 并验证:
bash运行
systemctl restart mysqld # 登录 MySQL,查看主库状态(File 和 Position 后续从库配置需用) mysql -uroot -p mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 156 | db1 | | | +------------------+----------+--------------+------------------+-------------------+
步骤 2:配置从库(192.168.1.103)
- 编辑 MySQL 配置文件:
bash运行
vim /etc/my.cnf - 添加以下配置(指定从库 ID,开启中继日志):
ini
[mysqld] server-id = 103 # 唯一 ID(与主库不同) relay-log = relay-bin # 开启中继日志(从库同步主库日志用) replicate-do-db = db1 # 仅同步 db1 数据库(与主库一致) - 重启 MySQL 并配置同步:
bash运行
systemctl restart mysqld # 登录从库 MySQL mysql -uroot -p # 1. 停止从库同步(首次配置可跳过) mysql> stop slave; # 2. 配置主库信息(master_log_file 和 master_log_pos 取自主库 show master status 结果) mysql> change master to master_host='192.168.1.101', master_user='mycat', # 主库的 Mycat 用户(需有复制权限) master_password='123456', master_log_file='mysql-bin.000001', # 主库二进制日志文件名 master_log_pos=156; # 主库日志位置 # 3. 启动从库同步 mysql> start slave; # 4. 验证主从状态(Slave_IO_Running 和 Slave_SQL_Running 均为 Yes 则成功) mysql> show slave status\G;
- 主从复制失败排查:
- 若
Slave_IO_Running=No:检查主库 IP、端口、用户密码是否正确,主库防火墙是否开放 3306 端口。 - 若
Slave_SQL_Running=No:可能是主从库数据不一致(如主库已存在表,从库无),需先同步初始数据(如备份主库 db1 导入从库)。
- 若
二、Mycat 读写分离核心配置(修改 schema.xml)
Mycat 读写分离通过
schema.xml 中的 balance 参数(负载均衡策略)和 readHost 标签(从库配置)实现,核心是「指定从库地址,并开启读请求转发」。步骤 1:修改 schema.xml 配置
bash
运行
vim /usr/local/mycat/conf/schema.xml
替换为以下配置(重点关注
balance="1" 和 readHost 节点):xml
<?xml version="1.0" encoding="UTF-8"?>
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 逻辑库:与 server.xml 中 schema 一致 -->
<schema name="mycat_db" checkSQLschema="false" sqlMaxLimit="100">
<!-- 逻辑表:仅关联主库所在的分片 dn1(本次演示单库读写分离,不分库) -->
<table name="user" dataNode="dn1" primaryKey="id" />
</schema>
<!-- 分片:仅关联主库的 db1 数据库 -->
<dataNode name="dn1" dataHost="host1" database="db1" />
<!-- 真实数据库主机配置(核心:主库+从库) -->
<dataHost name="host1"
maxCon="1000" minCon="10"
balance="1" <!-- 开启读写分离(关键参数) -->
writeType="0" <!-- 写请求转发到第一个 writeHost -->
dbType="mysql" dbDriver="native">
<!-- 心跳检测:确保数据库存活 -->
<heartbeat>select 1</heartbeat>
<!-- 主库配置(writeHost:负责写请求) -->
<writeHost host="host1-master"
url="192.168.1.101:3306"
user="mycat"
password="123456">
<!-- 从库配置(readHost:负责读请求,关联到父 writeHost) -->
<readHost host="host1-slave"
url="192.168.1.103:3306"
user="mycat"
password="123456" />
</readHost>
</dataHost>
</mycat:schema>
关键参数说明(重点理解)
| 参数 | 取值与含义 |
|---|---|
balance |
读写分离负载均衡策略(核心参数):
- 0:不开启读写分离(所有请求走主库); - 1:开启,读请求转发到所有 readHost; - 2:开启,读请求转发到所有 writeHost 和 readHost; - 3:开启,读请求转发到 readHost,且忽略 writeHost 的读权限 |
writeType |
写请求转发策略:
- 0:写请求转发到第一个可用的 writeHost; - 1:写请求随机转发到多个 writeHost(适合双主架构) |
readHost |
从库节点,必须嵌套在 writeHost 下,标识该从库是对应主库的从节点(Mycat 会自动关联主从关系) |
步骤 2:保持 server.xml 配置不变
无需修改
server.xml,沿用之前的应用连接用户(mycat_app/123456):xml
<user name="mycat_app">
<property name="password">123456</property>
<property name="schema">mycat_db</property>
<property name="readOnly">false</property> <!-- 应用可读可写 -->
</user>
三、重启 Mycat 并验证读写分离
步骤 1:重启 Mycat
bash
运行
# 先停止之前的 Mycat 进程(若已启动)
/usr/local/mycat/bin/mycat stop
# 前台启动(查看日志,确认启动成功)
/usr/local/mycat/bin/mycat console
- 启动成功标志:日志中无报错,出现
Mycat Server startup successfully。
步骤 2:验证读写分离效果(核心环节)
通过「连接 Mycat 执行 SQL → 分别查看主库 / 从库日志 → 确认请求分发」的流程验证。
1. 连接 Mycat 并操作数据
bash
运行
# 用 MySQL 客户端连接 Mycat(8066 端口)
mysql -h127.0.0.1 -umycat_app -p123456 -P8066
# 切换到逻辑库
use mycat_db;
# 1. 写操作(INSERT:应该走主库)
INSERT INTO user (id, name, age) VALUES (5, '孙七', 30);
# 2. 读操作(SELECT:应该走从库)
SELECT * FROM user;
2. 验证写请求走主库
登录主库(192.168.1.101),查看 MySQL 日志,确认有写操作记录:
bash
运行
# 1. 开启主库通用日志(临时生效,重启失效)
mysql -uroot -p
mysql> set global general_log = on;
mysql> set global log_output = 'table'; # 日志写入 mysql.general_log 表
# 2. 查询日志,确认有 INSERT 操作(用户是 mycat_app)
mysql> select * from mysql.general_log where argument like '%INSERT INTO user%';
- 结果:能看到 Mycat 转发的 INSERT 请求(主库日志有记录)。
3. 验证读请求走从库
登录从库(192.168.1.103),同样查看日志,确认有读操作记录:
bash
运行
# 1. 开启从库通用日志
mysql -uroot -p
mysql> set global general_log = on;
mysql> set global log_output = 'table';
# 2. 查询日志,确认有 SELECT 操作
mysql> select * from mysql.general_log where argument like '%SELECT * FROM user%';
- 结果:能看到 Mycat 转发的 SELECT 请求(从库日志有记录,主库日志无该 SELECT 记录)。
4. 验证数据一致性
从库执行查询,确认主库的 INSERT 数据已同步:
sql
-- 从库执行
use db1;
select * from user; # 应能看到 id=5 的「孙七」记录(主从复制生效)
四、进阶配置:双主双从(高可用)
若需更高可用性(主库故障自动切换),可配置「双主双从」架构,核心是添加多个
writeHost 和 readHost:xml
<dataHost name="host1"
balance="1"
writeType="1" <!-- 写请求随机转发到多个 writeHost -->
switchType="1" <!-- 主库故障自动切换(1=自动切换) -->
dbType="mysql" dbDriver="native">
<heartbeat>select 1</heartbeat>
<!-- 主库 1 + 从库 1 -->
<writeHost host="host1-master" url="192.168.1.101:3306" user="mycat" password="123456">
<readHost host="host1-slave" url="192.168.1.103:3306" user="mycat" password="123456" />
</writeHost>
<!-- 主库 2 + 从库 2(主库 1 故障时,自动切换到主库 2) -->
<writeHost host="host2-master" url="192.168.1.102:3306" user="mycat" password="123456">
<readHost host="host2-slave" url="192.168.1.104:3306" user="mycat" password="123456" />
</writeHost>
</dataHost>
- 关键参数:
switchType="1"(开启主库故障自动切换,基于心跳检测)。
五、新手常见坑与解决方案
| 常见问题 | 原因 | 解决方案 |
|---|---|---|
| 读请求仍走主库 | 1. balance 参数配置错误(如为 0);2. 从库未配置 readHost;3. 应用用户设置 readOnly="true" |
1. 确认 balance="1";2. 检查 readHost 配置是否嵌套在 writeHost 下;3. 确保 server.xml 中 readOnly="false" |
| 从库查询不到主库数据 | MySQL 主从复制未生效 | 1. 重新检查主从配置(show slave status\G 确认两个 Yes);2. 主库执行 flush logs 触发日志同步;3. 从库执行 start slave 重启同步 |
| Mycat 连接从库失败 | 1. 从库未开放 3306 端口;2. Mycat 用户无从库访问权限;3. 从库 MySQL 未启动 | 1. 开放端口:firewall-cmd --permanent --add-port=3306/tcp && firewall-cmd --reload;2. 从库重新授权 Mycat 用户;3. 启动从库 MySQL |
| 主库故障后未自动切换 | 1. switchType 参数未设置为 1;2. 心跳检测失败;3. 备用主库不可用 |
1. 配置 switchType="1";2. 检查心跳语句 select 1 是否能正常执行;3. 确保备用主库 MySQL 正常运行 |
六、核心总结
- Mycat 读写分离的核心是「
balance参数 +readHost配置」,无需修改应用代码,透明接入。 - 数据一致性依赖 MySQL 主从复制,Mycat 仅负责请求转发,需先确保主从同步正常。
- 新手优先从「一主一从」入手,熟悉后再拓展「双主双从」高可用架构。
- 排查问题时,优先查看 Mycat 日志(
/usr/local/mycat/logs/mycat.log)和 MySQL 通用日志,定位请求转发是否正常。
通过以上配置,即可实现 Mycat 读写分离,让读请求分担到从库,显著提升系统并发处理能力~
阅读剩余
版权声明:
作者:SE_Yang
链接:https://www.cnesa.cn/9251.html
文章版权归作者所有,未经允许请勿转载。
THE END
相关推荐