虽然MyCAT中间件几年前就已不再更新,但目前市场上还是有不少存量使用MyCAT分库分表架构的场景,因此有必要了解其核心原理与使用方式:
- 官网:http://mycat.org.cn/ 、http://mycatone.top/
- GitHub:https://github.com/MyCATApache/Mycat-Server 、 https://github.com/MyCATApache/Mycat2
- 参考教程:【13. 运维-分库分表-MyCat概述-安装】https://www.bilibili.com/video/BV1Jy1TBvEKe?vd_source=12b52fbafa48eae3751b0f9f4c99b016
一、基本介绍和架构
1. MyCAT 定位与核心价值
MyCAT 是基于 MySQL 协议的开源分布式数据库中间件,核心定位是「数据库层的负载均衡与分库分表网关」:
- 对应用层完全透明:应用只需连接 MyCAT(如同连接普通 MySQL),无需感知底层物理库的分片逻辑;
- 核心能力:SQL 解析、分片路由、结果聚合、读写分离、故障切换;
- 解决的核心问题:单库数据量过大(如千万级+)导致的性能瓶颈,实现数据水平拆分(分库分表)。
2. MyCAT 整体架构(分层设计)

各层核心职责:
| 层级 | 核心组件 | 职责说明 |
|---|---|---|
| 接入层 | 前端连接池、MySQL协议解析 | 接收应用的MySQL连接请求,兼容MySQL协议,管理前端连接(8066业务端口/9066管理端口) |
| 核心层 | SQL解析器 | 解析SQL语句,提取表名、分片键、操作类型(增删改查)等关键信息 |
| 分片路由引擎 | 根据rule.xml的分片规则,计算SQL应路由到哪些dataNode(数据节点) |
|
| 结果聚合引擎 | 将多个物理节点返回的结果集合并、排序、分页,返回统一结果给应用 | |
| 连接池管理 | 管理MyCat到后端MySQL的连接池(对应dataHost的maxCon/minCon配置) |
|
| 数据节点层 | dataNode/dataHost | 映射到实际的MySQL物理库,执行路由后的SQL,返回结果给核心层 |
3. MyCAT 与传统数据库架构的对比
| 架构类型 | 架构特点 | 痛点 | MyCat 分布式架构 | 优势 |
|---|---|---|---|---|
| 单库单表 | 所有数据存在一个MySQL实例的一张表 | 数据量达千万级后查询/写入卡顿 | 数据拆分到多个MySQL实例的多张表 | 分散存储压力,提升并发性能 |
| 单库多表 | 同实例内分表,未拆分数据库 | 实例级瓶颈(CPU/IO/内存) | 跨实例分库分表 | 突破单实例资源限制 |
| 应用层分库分表 | 应用代码硬编码分片规则 | 代码耦合度高,维护成本高 | 中间件层统一管理分片规则 | 应用无感知,规则可动态调整 |
4. MyCAT 核心设计理念
(1)「逻辑库/逻辑表」与「物理库/物理表」的解耦
- 逻辑层(对外) :MyCAT 暴露的
DB01(逻辑库)、TB_ORDER(逻辑表)是应用直接操作的对象,与普通 MySQL 库表无差异; - 物理层(对内) :逻辑表
TB_ORDER被拆分到dn1/dn2/dn3三个数据节点,对应 3 个 MySQL 实例的db01.TB_ORDER物理表; - 解耦价值:应用无需修改代码,只需调整 MyCAT 配置即可变更分片规则/物理节点,适配数据量增长。
(2)分片核心:「分片键」与「分片规则」
- 分片键 :决定数据路由的字段(如
TB_ORDER.id),是分库分表的核心依据; - 分片规则 :MyCAT 内置多种规则(如
auto-sharding-long按长整型范围分片、mod-long按取模分片、hash-int哈希分片等);auto-sharding-long规则:基于autopartition-long.txt中的范围配置(如 0-1000000 到 dn1,1000001-2000000 到 dn2 等),将不同id范围的数据路由到不同节点;
- 规则设计原则:分片键需选查询高频字段(如订单ID、用户ID),避免跨节点全表扫描(MyCAT 跨节点聚合性能较差)。
(3)连接池与高可用设计
- 前端连接池:MyCAT 对应用侧的连接进行管理,默认支持高并发连接;
- 后端连接池 :
dataHost配置的maxCon/minCon是 MyCAT 到每个 MySQL 实例的连接池大小,避免频繁创建/销毁连接; - 高可用 :
dataHost的switchType="1"开启心跳检测(select user()),当某个writeHost宕机时,MyCAT 自动切换到备用节点(若配置),保障服务可用。
(4)全局序列(自增主键)
- 配置中
TB_ORDER开启autoIncrement="true",解决分布式场景下主键自增冲突问题:- MyCAT 提供全局序列生成器(如
HttpIncrSequenceHandler),保证不同物理节点的TB_ORDER.id全局唯一; - 对比原生 MySQL 自增:单实例自增主键无法跨实例保证唯一,MyCAT 全局序列是分布式分表的必备能力。
- MyCAT 提供全局序列生成器(如
二、实验节点规划
1. 节点信息表
| 节点类型 | 节点名称/IP | 端口 | 作用说明 | 相关配置关联 |
|---|---|---|---|---|
| MyCAT 服务节点 | 192.168.31.122 | 8066(业务)、9066(管理) | 部署MyCAT服务,提供逻辑库访问入口,处理分库分表路由、转发SQL请求 | server.xml、schema.xml |
| MySQL 物理节点1 | 192.168.31.123(dhost1) | 3306 | 存储分片数据节点dn1,对应物理库db01,接收MyCat转发的SQL操作 | schema.xml中dn1、dhost1 |
| MySQL 物理节点2 | 192.168.31.124(dhost2) | 3306 | 存储分片数据节点dn2,对应物理库db01,接收MyCat转发的SQL操作 | schema.xml中dn2、dhost2 |
| MySQL 物理节点3 | 192.168.31.125(dhost3) | 3306 | 存储分片数据节点dn3,对应物理库db01,接收MyCat转发的SQL操作 | schema.xml中dn3、dhost3 |
| 逻辑库 | DB01(MyCat逻辑库) | - | 对外暴露的统一数据库入口,屏蔽底层物理库差异 | server.xml、schema.xml |
| 逻辑表 | TB_ORDER(分片表) | - | 对外暴露的统一数据表,数据按分片规则分布在3个MySQL物理节点的db01库中 | schema.xml、rule.xml |
说明:MySQL 部署流程不再赘述,以下操作均以已部署好三个 MySQL 单机节点为前提。
2. 实验架构可视化
物理数据库层
MyCat 中间件层
应用层
Java/PHP/Python应用
接入层
8066/9066端口
MySQL协议兼容
核心层
SQL解析+路由+聚合
配置层
schema.xml/server.xml/rule.xml
MySQL节点1
192.168.31.123:3306
db01.TB_ORDER
MySQL节点2
192.168.31.124:3306
db01.TB_ORDER
MySQL节点3
192.168.31.125:3306
db01.TB_ORDER
三、部署与使用
1. MyCAT 目录结构
(1)服务器级目录结构(部署路径)
/
├── data/
│ ├── pkg/ # 安装包存放目录
│ │ ├── Mycat-server-1.6.7.5-release-20200422133810-linux.tar.gz # MyCat安装包
│ │ ├── mysql-connector-j-8.0.33.tar.gz # MySQL驱动安装包
│ │ ├── mysql-connector-j-8.0.33/ # 驱动解压目录
│ │ └── mysql-connector-java-5.1.35.jar # 旧驱动备份文件
│ └── mycat/ # MyCat核心目录(解压后根目录)
│ ├── bin/ # 可执行文件目录(启动/停止脚本)
│ ├── catlet/ # 多表联查相关扩展目录(无需重点关注)
│ ├── conf/ # 核心配置文件目录
│ ├── lib/ # 项目依赖包目录(jar包,含MySQL驱动)
│ └── logs/ # 日志文件目录(运行日志、错误日志等)
└── usr/
└── lib/jvm/ # JDK安装目录(java-1.8.0-openjdk)
(2)MyCAT 核心目录(/data/mycat/)详细结构
/data/mycat/
├── bin/ # 操作脚本目录
│ ├── mycat # 核心脚本(start/stop/status等操作)
│ └── 其他辅助脚本 # 无需手动修改
├── catlet/ # 扩展目录
│ └── 自定义catlet相关类 # 多表联查扩展实现,默认无需改动
├── conf/ # 配置文件核心目录
│ ├── schema.xml # 逻辑库、逻辑表、数据节点、物理主机配置(核心)
│ ├── schema.xml.bak # schema.xml备份文件
│ ├── server.xml # 用户账号、权限、系统参数配置(核心)
│ ├── server.xml.bak # server.xml备份文件
│ ├── rule.xml # 分片规则配置文件
│ ├── autopartition-long.txt # 长整型分片规则配置文件
│ ├── schema.dtd # schema.xml语法约束文件
│ ├── server.dtd # server.xml语法约束文件
│ └── 其他配置文件 # 如log4j2.xml(日志配置)等
├── lib/ # 依赖包目录
│ ├── mysql-connector-j-8.0.33.jar # 替换后的新版MySQL驱动
│ ├── mycat-server-1.6.7.5.jar # MyCat核心jar包
│ └── 其他第三方依赖jar包 # 如spring、netty等
└── logs/ # 日志目录
├── mycat.log # MyCat运行日志
├── wrapper.log # 包装器日志
├── sql.log # SQL执行日志
└── 其他日志文件 # 如慢查询日志、错误日志等
(3)目录核心文件说明
| 目录路径 | 核心文件/目录 | 作用说明 |
|---|---|---|
| /data/mycat/bin/ | mycat | 启动、停止、查看MyCat状态的核心脚本,执行./mycat start即可启动服务 |
| /data/mycat/conf/ | schema.xml | 定义逻辑库、逻辑表、数据节点与物理主机的映射关系,是分库分表核心配置 |
| /data/mycat/conf/ | server.xml | 配置MyCat登录用户、密码、权限及系统全局参数(如端口、超时时间) |
| /data/mycat/conf/ | rule.xml | 定义分片规则名称与具体实现的关联,配合分片配置文件使用 |
| /data/mycat/lib/ | mysql-connector-j-8.0.33.jar | 连接MySQL物理节点的驱动包,需替换为高版本以兼容新版MySQL |
| /data/mycat/logs/ | mycat.log | 记录MyCat运行过程中的关键信息,用于排查启动失败、SQL路由异常等问题 |
(4)关键补充说明
- 目录权限 :MyCAT相关目录(尤其是lib、logs)需保证运行用户有读写权限,文中已通过
chmod 777设置驱动包权限; - 核心端口:MyCAT默认占用8066(业务访问端口,用于mysql客户端连接)、9066(管理端口,用于运维管理);
- 配置备份:修改核心配置文件(schema.xml、server.xml)前,建议按日期备份(如.20251206后缀),便于故障回滚。
2. 安装MyCAT
(1)安装JDK(MyCAT运行依赖)
sh
dnf install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
java -version
(2)安装MyCAT主程序
sh
mkdir /data/pkg
cd /data/pkg
wget https://github.com/MyCATApache/Mycat-Server/releases/download/Mycat-server-1675-release/Mycat-server-1.6.7.5-release-20200422133810-linux.tar.gz
tar -zxvf ./Mycat-server-1.6.7.5-release-20200422133810-linux.tar.gz -C /data/
cd /data/mycat
mkdir ./logs
ll
(3)替换高版本MySQL驱动(解决兼容性问题)
sh
cd /data/pkg/
ll /data/mycat/lib/mysql-connector-java-*
# 备份旧驱动
mv /data/mycat/lib/mysql-connector-java-5.1.35.jar /data/pkg/
# 下载并解压新版驱动
wget https://downloads.mysql.com/archives/get/p/3/file/mysql-connector-j-8.0.33.tar.gz
tar -zxvf mysql-connector-j-8.0.33.tar.gz
cp /data/pkg/mysql-connector-j-8.0.33/mysql-connector-j-8.0.33.jar /data/mycat/lib/
# 修改权限
chmod 777 /data/mycat/lib/mysql-connector-java-*
ll /data/mycat/lib/mysql-connector-java-*
3. 配置MyCAT
(1)配置schema.xml(核心映射关系)
sh
cd /data/mycat/conf
cp /data/mycat/conf/schema.xml /data/mycat/conf/schema.xml.bak
vi /data/mycat/conf/schema.xml
配置内容:
xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="DB01" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="TB_ORDER" primaryKey="id" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" autoIncrement="true" fetchStoreNodeByJdbc="true">
</table>
</schema>
<dataNode name="dn1" dataHost="dhost1" database="db01" />
<dataNode name="dn2" dataHost="dhost2" database="db01" />
<dataNode name="dn3" dataHost="dhost3" database="db01" />
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.31.123:3306?useSSL=false&serverTimezone=Asia/Shanghai" user="root" password="root.COM2025*">
</writeHost>
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.31.124:3306?useSSL=false&serverTimezone=Asia/Shanghai" user="root" password="root.COM2025*">
</writeHost>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.31.125:3306?useSSL=false&serverTimezone=Asia/Shanghai" user="root" password="root.COM2025*">
</writeHost>
</dataHost>
</mycat:schema>
(2)MySQL用户认证插件调整(兼容MyCAT)
sql
-- 登录MySQL,修改用户认证插件为mysql_native_password
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root.COM2025*';
FLUSH PRIVILEGES;
(3)配置server.xml(用户与权限)
sh
cd /data/mycat/conf
cp /data/mycat/conf/server.xml /data/mycat/conf/server.xml.bak
vi /data/mycat/conf/server.xml
核心修改内容(仅保留用户密码和schema相关):
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property>
<property name="ignoreUnknownCommand">0</property>
<property name="useHandshakeV10">1</property>
<property name="removeGraveAccent">1</property>
<property name="useSqlStat">0</property>
<property name="useGlobleTableCheck">0</property>
<property name="sqlExecuteTimeout">300</property>
<property name="sequenceHandlerType">1</property>
<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
<property name="subqueryRelationshipCheck">false</property>
<property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property>
<property name="processorBufferPoolType">0</property>
<property name="handleDistributedTransactions">0</property>
<property name="useOffHeapForMerge">0</property>
<property name="memoryPageSize">64k</property>
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<property name="systemReserveMemorySize">384m</property>
<property name="useZKSwitch">false</property>
<property name="strictTxIsolation">false</property>
<property name="parallExecute">0</property>
</system>
<user name="root" defaultAccount="true">
<property name="password">root.COM2025*</property>
<property name="schemas">DB01</property>
</user>
<user name="user">
<property name="password">123456</property>
<property name="schemas">DB01</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
4. 启动与管理MyCAT
(1)基础启停命令
sh
cd /data/mycat/
./bin/mycat start
./bin/mycat stop
(2)配置systemctl服务(便捷管理)
创建 /usr/lib/systemd/system/mycat.service 文件:
ini
[Unit]
Description=MyCat Service
After=network.target
[Service]
Type=forking
ExecStart=/data/mycat/bin/mycat start
ExecStop=/data/mycat/bin/mycat stop
ExecReload=/data/mycat/bin/mycat restart
User=root # 可根据实际运行用户调整
Restart=on-failure
[Install]
WantedBy=multi-user.target
核心systemctl命令:
sh
# 重新加载服务配置
systemctl daemon-reload
# 启动
systemctl start mycat
# 停止
systemctl stop mycat
# 重启
systemctl restart mycat
# 设置开机自启
systemctl enable mycat
# 查看状态
systemctl status mycat
5. 访问与验证MyCAT
(1)登录MyCAT
sh
mysql -h 192.168.31.122 -P 8066 -uroot -p"root.COM2025*"
(2)确认连接信息
sql
\s
--------------
mysql Ver 8.4.0 for Linux on x86_64 (MySQL Community Server - GPL)
Connection id: 1
Current database: db01
Current user: root@192.168.31.122
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.6.29-mycat-1.6.7.5-release-20200422133810 MyCat Server (OpenCloudDB)
Protocol version: 10
Connection: 192.168.31.122 via TCP/IP
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4
TCP port: 8066
Binary data as: Hexadecimal
--------------
(3)验证逻辑库/表并创建物理表
sql
-- 查看逻辑库
show databases;
-- 切换到逻辑库
use DB01;
-- 查看逻辑表
show tables;
-- 创建分片表
CREATE TABLE TB_ORDER (
id BIGINT(20) NOT NULL,
title VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8 ;
-- 插入测试数据
INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
INSERT INTO TB_ORDER(id,title) VALUES(1000000,'goods1000000 ');
INSERT INTO TB_ORDER(id,title) VALUES(4000000,'goods4000000');
INSERT INTO TB_ORDER(id,title) VALUES(4000001,'goods4000001');
INSERT INTO TB_ORDER(id,title) VALUES(8000000,'goods8000000');
INSERT INTO TB_ORDER(id,title) VALUES(10000001,'goods10000001');
INSERT INTO TB_ORDER(id,title) VALUES(15000001,'goods15000001'); -- 超出规则范围
-- 查询数据(验证分片效果)
SELECT * FROM TB_ORDER;
-- 查看分片规则配置
-- 执行以下Shell命令
cd /data/mycat/conf/
cat ./rule.xml
cat ./autopartition-long.txt
四、配置文件详解
1. schema标签
xml
<schema name="DB01" checkSQLschema="true" sqlMaxLimit="100">
<table name="TB_ORDER" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
作用说明
- schema标签用于定义MyCAT实例中的逻辑库;
- 一个MyCAT实例可包含多个逻辑库;
- MyCAT的逻辑库等同于MySQL中的database概念,操作表时需切换到对应逻辑库。
核心属性
- name:指定自定义的逻辑库库名;
- checkSQLschema :SQL语句中指定数据库名时,执行是否自动去除
true:自动去除;false:不自动去除;
- sqlMaxLimit:未指定limit的列表查询,默认返回的记录条数。
2. schema标签的table子标签
xml
<schema name="DB01" checkSQLschema="true" sqlMaxLimit="100">
<table name="TB_ORDER" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
作用说明
- table标签用于定义MyCAT逻辑库(schema)下的逻辑表;
- 所有需要拆分的表都需在此标签中定义。
核心属性
- name:逻辑表的表名,在当前逻辑库下唯一;
- dataNode:逻辑表所属的dataNode,需与dataNode标签的name对应;多个dataNode用逗号分隔;
- rule:分片规则名称,该名称在rule.xml中定义;
- primaryKey:逻辑表对应真实表的主键;
- type :逻辑表类型,可选值:
- 不配置:默认是普通表;
global:全局表。
3. dataNode标签
xml
<dataNode name="dn1" dataHost="dhost1" database="db01" />
<dataNode name="dn2" dataHost="dhost2" database="db01" />
<dataNode name="dn3" dataHost="dhost3" database="db01" />
作用说明
- dataNode标签用于定义MyCAT中的数据节点(即数据分片);
- 一个dataNode对应一个独立的数据分片。
核心属性
- name:数据节点的名称;
- dataHost:数据库实例的主机名称,需与dataHost标签的name属性对应;
- database:该分片对应的实际数据库名称。
4. dataHost标签
xml
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.200.210:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="1234">
</writeHost>
</dataHost>
作用说明
- 该标签是MyCAT逻辑库的底层配置;
- 用于定义具体数据库实例、读写分离规则、心跳检测语句。
核心属性
- name:唯一标识,供上层标签(如dataNode)引用;
- maxCon/minCon:数据库连接池的最大/最小连接数;
- balance:负载均衡策略,可选值为0、1、2、3;
- writeType :写操作的分发方式
- 0:写操作优先转发到第一个writeHost,挂了则切换到下一个;
- 1:写操作随机分发到已配置的writeHost;
- dbDriver :数据库驱动类型,支持
native、jdbc。
五、总结
1. 核心关键点
- 架构核心:MyCAT 采用「中间件网关」架构,通过逻辑层屏蔽物理层的分库分表细节,实现应用无感知的分布式数据存储;
- 配置核心 :
schema.xml定义逻辑-物理映射关系,rule.xml定义分片规则,server.xml定义用户权限,三者共同支撑分库分表逻辑; - 设计关键:分片键选择、规则匹配、连接池配置是 MyCAT 性能和可用性的核心,需结合业务查询场景设计(避免跨节点全表扫描)。
2. 生产落地建议
- 分片键优先选择「查询高频、更新低频」的字段(如订单ID、用户ID);
- 对跨节点的聚合查询(如
count(*)、sum())做缓存优化,避免频繁触发 MyCAT 全节点扫描; - 定期监控 MyCAT 日志(
mycat.log/sql.log),排查慢SQL和路由异常; - 高可用部署:MyCAT 建议双节点部署(避免单点故障),后端 MySQL 建议主从架构,配合
dataHost的balance配置实现读写分离。