MySQL分布式架构:MyCat详解

MyCat 是一款基于 Java 开发的分布式数据库中间件,专注于解决 MySQL 分库分表、读写分离、高可用等问题,被誉为"开源的分布式数据库系统"。它兼容 MySQL 协议,应用程序可以像连接普通 MySQL 一样连接 MyCat,无需修改代码。

一、MyCat 核心功能与架构

1. 核心功能
  • 分库分表:支持水平分片(按行)和垂直分片(按表)
  • 读写分离:自动将读操作分发到从库,写操作到主库
  • 高可用:支持主从切换、故障自动检测
  • 分布式事务:支持 XA 分布式事务和柔性事务
  • SQL 拦截与改写:对 SQL 进行解析、优化和路由
2. 架构组成
复制代码
应用程序 → MyCat 集群 → 后端 MySQL 集群
  • MyCat 层:负责 SQL 解析、路由、结果聚合
  • MySQL 层:实际存储数据的数据库集群(主从、多节点)

二、安装与配置(Linux 环境)

1. 环境准备
  • JDK 1.8+(MyCat 基于 Java 开发)
  • MySQL 5.7+(后端数据库)
bash 复制代码
# 安装 JDK
yum install -y java-1.8.0-openjdk-devel

# 验证 Java 环境
java -version
2. 安装 MyCat
bash 复制代码
# 下载 MyCat(以 1.6.7.6 版本为例)
wget http://dl.mycat.org.cn/1.6.7.6/20220524173849/Mycat-server-1.6.7.6-release-20220524173849-linux.tar.gz

# 解压到 /usr/local
tar -zxvf Mycat-server-1.6.7.6-release-20220524173849-linux.tar.gz -C /usr/local

# 配置环境变量
echo 'export MYCAT_HOME=/usr/local/mycat' >> /etc/profile
echo 'export PATH=$PATH:$MYCAT_HOME/bin' >> /etc/profile
source /etc/profile
3. 核心配置文件

MyCat 的配置文件位于 $MYCAT_HOME/conf 目录,关键文件包括:

  • server.xml:定义用户、权限、端口等
  • schema.xml:定义逻辑库、表、分片规则、后端数据源
  • rule.xml:定义分片规则(如按范围、哈希分片)

三、核心配置详解

1. server.xml(用户与权限配置)
xml 复制代码
<mycat:server xmlns:mycat="http://io.mycat/">
    <!-- 定义连接 MyCat 的用户 -->
    <user name="test">
        <property name="password">test123</property>
        <!-- 关联的逻辑库 -->
        <property name="schemas">TESTDB</property>
        <!-- 只读权限设置 -->
        <property name="readOnly">false</property>
    </user>
    
    <!-- 管理用户 -->
    <user name="mycat">
        <property name="password">123456</property>
        <property name="schemas">TESTDB</property>
        <property name="manager">true</property>
    </user>
    
    <!-- 系统参数 -->
    <system>
        <property name="defaultSqlParser">druidparser</property>
        <property name="serverPort">8066</property>  <!-- 数据端口 -->
        <property name="managerPort">9066</property> <!-- 管理端口 -->
    </system>
</mycat:server>
2. schema.xml(逻辑库与数据源配置)
xml 复制代码
<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- 逻辑库 TESTDB -->
    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
        <!-- 逻辑表 t_order,按 id 分片 -->
        <table name="t_order" dataNode="dn1,dn2" rule="mod-long" />
    </schema>
    
    <!-- 数据节点(dn1 对应主机 host1 的 db1 库) -->
    <dataNode name="dn1" dataHost="host1" database="db1" />
    <dataNode name="dn2" dataHost="host2" database="db2" />
    
    <!-- 数据源配置(主从架构) -->
    <dataHost name="host1" maxCon="1000" minCon="10" balance="1"
              writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- 主库 -->
        <writeHost host="hostM1" url="jdbc:mysql://192.168.1.100:3306" user="root" password="123456">
            <!-- 从库 -->
            <readHost host="hostS1" url="jdbc:mysql://192.168.1.101:3306" user="root" password="123456" />
        </writeHost>
    </dataHost>
    
    <dataHost name="host2" maxCon="1000" minCon="10" balance="1"
              writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="hostM2" url="jdbc:mysql://192.168.1.102:3306" user="root" password="123456">
            <readHost host="hostS2" url="jdbc:mysql://192.168.1.103:3306" user="root" password="123456" />
        </writeHost>
    </dataHost>
</mycat:schema>

关键参数说明:

  • balance="1":读操作负载均衡(从库参与读取)
  • writeType="0":写操作只发往第一个 writeHost
  • switchType="1":主库故障自动切换到从库
3. rule.xml(分片规则配置)

以"取模分片"为例:

xml 复制代码
<mycat:rule xmlns:mycat="http://io.mycat/">
    <!-- 按 id 取模分片 -->
    <tableRule name="mod-long">
        <rule>
            <columns>id</columns>  <!-- 分片字段 -->
            <algorithm>mod-long</algorithm>  <!-- 算法名称 -->
        </rule>
    </tableRule>
    
    <!-- 取模算法配置(2 个分片) -->
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <property name="count">2</property>  <!-- 分片数量 -->
    </function>
</mycat:rule>

其他常用分片规则:

  • PartitionByRange:按范围分片(如 id 1-1000 到 dn1)
  • PartitionByHash:按哈希值分片
  • PartitionByDate:按日期分片(如按月份)

四、启动与管理

1. 启动 MyCat
bash 复制代码
# 启动
mycat start

# 停止
mycat stop

# 重启
mycat restart

# 查看状态
mycat status
2. 连接 MyCat
bash 复制代码
# 连接数据端口(8066)
mysql -h127.0.0.1 -P8066 -utest -ptest123

# 连接管理端口(9066,用于管理操作)
mysql -h127.0.0.1 -P9066 -umycat -p123456
3. 管理命令(通过 9066 端口)
sql 复制代码
-- 查看数据节点状态
show dataNode;

-- 查看数据源状态
show dataHost;

-- 手动切换主从
switch @@dataHost=host1/writeHost=hostM1;

-- 重新加载配置
reload @@config;

五、分库分表示例

假设对 t_order 表按 id 取模分表到 2 个数据节点(dn1、dn2):

  1. 创建逻辑表:通过 MyCat 连接执行

    sql 复制代码
    CREATE TABLE t_order (
        id INT NOT NULL,
        user_id INT NOT NULL,
        create_time DATETIME,
        PRIMARY KEY (id)
    );

    MyCat 会自动在 dn1(db1.t_order)和 dn2(db2.t_order)创建物理表。

  2. 插入数据

    sql 复制代码
    -- id=1 会路由到 dn1(1%2=1 → 索引从0开始时可能到 dn1)
    INSERT INTO t_order(id, user_id, create_time) VALUES(1, 100, NOW());
    
    -- id=2 会路由到 dn2(2%2=0 → 索引从0开始时可能到 dn2)
    INSERT INTO t_order(id, user_id, create_time) VALUES(2, 101, NOW());
  3. 查询数据

    sql 复制代码
    -- MyCat 会自动聚合 dn1 和 dn2 的结果
    SELECT * FROM t_order;

六、读写分离配置

schema.xml 中通过 balance 参数控制读写分离策略:

  • balance="0":不开启读写分离,所有操作走主库
  • balance="1":读操作分发到从库,写操作走主库
  • balance="2":读操作随机分发到主库和从库

强制走主库查询:

sql 复制代码
-- 通过注解强制读主库
SELECT /*+ MYCAT:db_type=master */ * FROM t_order;

七、高可用与监控

  1. 主库故障自动切换

    • 配置 switchType="1" 开启自动切换
    • MyCat 通过心跳检测(heartbeat 配置)判断主库状态
  2. 监控

    • 集成 MyCat-Web 监控平台(需单独部署)
    • 查看日志:$MYCAT_HOME/logs/mycat.log

八、注意事项

  1. 避免跨分片事务(复杂且性能低)
  2. 分片字段尽量在 WHERE 条件中,否则会全表扫描
  3. 大表分片时提前规划分片规则,避免后期数据迁移
  4. 定期备份后端 MySQL 数据,MyCat 不存储实际数据

MyCat 适合中小规模分布式场景,通过简单配置即可实现 MySQL 的水平扩展,是构建高可用、高性能数据库架构的重要工具。

相关推荐
SoleMotive.9 分钟前
kafka选型
分布式·kafka
梁萌1 小时前
ShardingSphere分库分表实战
数据库·mysql·实战·shardingsphere·分库分表
川石课堂软件测试1 小时前
Mysql中触发器使用详详详详详解~
数据库·redis·功能测试·mysql·oracle·单元测试·自动化
鹏说大数据1 小时前
数据治理项目实战系列6-数据治理架构设计实战,流程 + 工具双架构拆解
大数据·数据库·架构
程序员游老板1 小时前
基于SpringBoot3_vue3_MybatisPlus_Mysql_Maven的社区养老系统/养老院管理系统
java·spring boot·mysql·毕业设计·软件工程·信息与通信·毕设
唯余旧忆1 小时前
【数据写入】达梦数据库(dm8)merge into写入时序数据速度慢的问题处理
数据库
小二·2 小时前
MyBatis基础入门《十五》分布式事务实战:Seata + MyBatis 实现跨服务数据一致性
分布式·wpf·mybatis
小二·2 小时前
MyBatis基础入门《十四》多租户架构实战:基于 MyBatis 实现 SaaS 系统的动态数据隔离
数据库·架构·mybatis
白衣衬衫 两袖清风2 小时前
SQL联查案例
数据库·sql
ShirleyWang0122 小时前
VMware如何导入vmdk文件
linux·数据库