Mycat 读写分离的核心逻辑是:写请求(INSERT/UPDATE/DELETE)转发到主库(writeHost),读请求(SELECT)转发到从库(readHost),应用无需修改代码,仅需通过 Mycat 配置实现流量分发,从而提升系统并发能力。
以下基于之前的 Mycat 入门环境,详细讲解「一主一从」架构的读写分离配置(最常用场景),包含「主从复制准备→Mycat 配置→验证效果」全流程。
- 已安装 Mycat(1.6.x 稳定版,之前入门环境可直接复用)。
- 2 台 MySQL 服务器(CentOS 系统),需先搭建 MySQL 主从复制(Mycat 不负责数据同步,仅负责请求转发,数据一致性依赖 MySQL 自身主从复制):
- 主库(Master):
192.168.1.101:3306,数据库 db1(已创建)。
- 从库(Slave):
192.168.1.103:3306,数据库 db1(需手动创建,与主库一致)。
- 所有数据库已创建 Mycat 连接用户(
mycat/123456),并授予权限:
GRANT ALL ON *.* TO 'mycat'@'%' IDENTIFIED BY '123456';
FLUSH PRIVILEGES;
Mycat 读写分离的基础是「主从数据一致」,需先完成 MySQL 主从复制配置(以 MySQL 8.0 为例):
- 编辑 MySQL 配置文件:
- 添加以下配置(开启二进制日志,指定主库 ID):
[mysqld]
server-id = 101 # 唯一 ID(1-2^32-1,不能与从库重复)
log-bin = mysql-bin # 开启二进制日志(主从复制依赖)
binlog-do-db = db1 # 仅同步 db1 数据库(按需配置,不写则同步所有库)
- 重启 MySQL 并验证:
systemctl restart mysqld
mysql -uroot -p
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 156 | db1 | | |
+------------------+----------+--------------+------------------+-------------------+
- 编辑 MySQL 配置文件:
- 添加以下配置(指定从库 ID,开启中继日志):
[mysqld]
server-id = 103 # 唯一 ID(与主库不同)
relay-log = relay-bin # 开启中继日志(从库同步主库日志用)
replicate-do-db = db1 # 仅同步 db1 数据库(与主库一致)
- 重启 MySQL 并配置同步:
systemctl restart mysqld
mysql -uroot -p
mysql> stop slave;
mysql> change master to
master_host='192.168.1.101',
master_user='mycat',
master_password='123456',
master_log_file='mysql-bin.000001',
master_log_pos=156;
mysql> start slave;
mysql> show slave status\G;
- 主从复制失败排查:
- 若
Slave_IO_Running=No:检查主库 IP、端口、用户密码是否正确,主库防火墙是否开放 3306 端口。
- 若
Slave_SQL_Running=No:可能是主从库数据不一致(如主库已存在表,从库无),需先同步初始数据(如备份主库 db1 导入从库)。
Mycat 读写分离通过 schema.xml 中的 balance 参数(负载均衡策略)和 readHost 标签(从库配置)实现,核心是「指定从库地址,并开启读请求转发」。
vim /usr/local/mycat/conf/schema.xml
替换为以下配置(重点关注 balance="1" 和 readHost 节点):
<?xml version="1.0" encoding="UTF-8"?>
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycat_db" checkSQLschema="false" sqlMaxLimit="100">
<table name="user" dataNode="dn1" primaryKey="id" />
</schema>
<dataNode name="dn1" dataHost="host1" database="db1" />
<dataHost name="host1"
maxCon="1000" minCon="10"
balance="1" <!-- 开启读写分离(关键参数) -->
writeType="0"
dbType="mysql" dbDriver="native">
<heartbeat>select 1</heartbeat>
<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" />
</readHost>
</dataHost>
</mycat:schema>
无需修改 server.xml,沿用之前的应用连接用户(mycat_app/123456):
<user name="mycat_app">
<property name="password">123456</property>
<property name="schema">mycat_db</property>
<property name="readOnly">false</property>
</user>
/usr/local/mycat/bin/mycat stop
/usr/local/mycat/bin/mycat console
- 启动成功标志:日志中无报错,出现
Mycat Server startup successfully。
通过「连接 Mycat 执行 SQL → 分别查看主库 / 从库日志 → 确认请求分发」的流程验证。
mysql -h127.0.0.1 -umycat_app -p123456 -P8066
use mycat_db;
INSERT INTO user (id, name, age) VALUES (5, '孙七', 30);
SELECT * FROM user;
登录主库(192.168.1.101),查看 MySQL 日志,确认有写操作记录:
mysql -uroot -p
mysql> set global general_log = on;
mysql> set global log_output = 'table';
mysql> select * from mysql.general_log where argument like '%INSERT INTO user%';
- 结果:能看到 Mycat 转发的 INSERT 请求(主库日志有记录)。
登录从库(192.168.1.103),同样查看日志,确认有读操作记录:
mysql -uroot -p
mysql> set global general_log = on;
mysql> set global log_output = 'table';
mysql> select * from mysql.general_log where argument like '%SELECT * FROM user%';
- 结果:能看到 Mycat 转发的 SELECT 请求(从库日志有记录,主库日志无该 SELECT 记录)。
从库执行查询,确认主库的 INSERT 数据已同步:
use db1;
select * from user;
若需更高可用性(主库故障自动切换),可配置「双主双从」架构,核心是添加多个 writeHost 和 readHost:
<dataHost name="host1"
balance="1"
writeType="1" <!-- 写请求随机转发到多个 writeHost -->
switchType="1"
dbType="mysql" dbDriver="native">
<heartbeat>select 1</heartbeat>
<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>
<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"(开启主库故障自动切换,基于心跳检测)。
- Mycat 读写分离的核心是「
balance 参数 + readHost 配置」,无需修改应用代码,透明接入。
- 数据一致性依赖 MySQL 主从复制,Mycat 仅负责请求转发,需先确保主从同步正常。
- 新手优先从「一主一从」入手,熟悉后再拓展「双主双从」高可用架构。
- 排查问题时,优先查看 Mycat 日志(
/usr/local/mycat/logs/mycat.log)和 MySQL 通用日志,定位请求转发是否正常。
通过以上配置,即可实现 Mycat 读写分离,让读请求分担到从库,显著提升系统并发处理能力~