1. MyCat 2核心概念与实战价值
第一次接触MyCat 2时,我正面临一个电商项目的数据库性能瓶颈。当单表数据突破5000万行,简单的查询都要耗时3秒以上,更别提高峰期并发的订单创建了。这时我才真正理解什么是"分布式数据库中间件"——它就像个智能路由器,把海量数据分散存储,同时让应用层完全无感知。
MyCat 2最让我惊艳的是它对MySQL协议的完美兼容。记得第一次用Navicat连接8066端口时,界面显示的就是个普通MySQL服务器,但背后可能是几十个物理数据库在协同工作。这种透明化的设计让团队迁移成本极低,我们甚至不需要修改现有SQL语句。
读写分离的实战效果尤为明显。通过将查询请求自动路由到从库,主库的CPU负载直接从90%降到了35%。有次大促期间,一个跑在从库的复杂报表查询执行了8分钟,居然完全没有影响前台用户的正常下单——这要放在以前,整个数据库早就被拖垮了。
分库分表则是解决数据膨胀的终极方案。去年我们把用户表按ID哈希分散到16个库,每个库再拆成64张子表。现在单表数据量始终控制在800万条以内,索引查询稳定在20ms以下。最妙的是应用代码完全不用改,只是在MyCat配置里定义了分片规则。
2. 环境准备与安装部署
2.1 基础环境搭建
在CentOS 7上部署时,我建议先用Docker准备MySQL实例。这样既能快速搭建主从环境,又不会污染宿主机。以下是创建主库和从库的命令:
# 主库容器(暴露3307端口) docker run --name mysql-master -p 3307:3306 \ -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 \ --lower_case_table_names=1 --server-id=1 \ --log-bin=mysql-bin --binlog-format=ROW # 从库容器(暴露3308端口) docker run --name mysql-slave -p 3308:3306 \ -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 \ --lower_case_table_names=1 --server-id=2踩坑提醒:一定要设置server-id!我有次忘记配置,主从同步死活不成功,排查了半天才发现是这个基础参数缺失。另外建议统一设置lower_case_table_names,避免大小写敏感问题。
2.2 MyCat 2安装详解
官方提供的安装包其实是个模板,需要自己补充核心jar包。我整理了个一键安装脚本:
#!/bin/bash # 创建安装目录 mkdir -p /data/mycat/{conf,lib,logs} # 下载安装模板 wget http://dl.mycat.org.cn/2.0/install-template/mycat2-install-template-1.21.zip unzip mycat2-install-template-1.21.zip -d /data/mycat # 下载核心jar包 wget http://dl.mycat.org.cn/2.0/1.21-release/mycat2-1.21-release-jar-with-dependencies.jar mv mycat2-1.21-release-jar-with-dependencies.jar /data/mycat/lib/ # 设置执行权限 chmod +x /data/mycat/bin/*安装后目录结构特别清晰:
- /bin:启停脚本
- /conf:所有配置文件
- /lib:依赖库
- /logs:运行日志
启动前务必检查prototypeDs.datasource.json中的数据库连接信息,这是MyCat自带的原型数据源。我第一次启动时就因为密码错误导致连不上后端MySQL。
3. 读写分离实战配置
3.1 MySQL主从同步搭建
主从配置的关键步骤是创建复制账号和设置binlog位置。在主库执行:
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl123'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES; -- 查看binlog位置 SHOW MASTER STATUS;然后在从库配置同步:
CHANGE MASTER TO MASTER_HOST='宿主机IP', MASTER_PORT=3307, MASTER_USER='repl', MASTER_PASSWORD='repl123', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; START SLAVE; -- 检查状态 SHOW SLAVE STATUS\G验证技巧:在主库创建测试表,观察从库是否自动同步。如果Slave_IO_Running和Slave_SQL_Running都是Yes,说明配置成功。
3.2 MyCat读写分离配置
在MyCat中配置集群只需一条注释指令:
/*! mycat:createCluster{ "clusterType":"MASTER_SLAVE", "masters":["master_ds"], "replicas":["slave_ds"], "readBalanceType":"BALANCE_ALL", "name":"c0" }*/;这里readBalanceType支持三种模式:
- BALANCE_ALL(默认):所有从库随机选
- BALANCE_ALL_READ:主库也参与读负载
- BALANCE_NONE:全部走主库
实测发现个有趣现象:当在MyCat执行SELECT @@server_id时,每次返回的值可能不同,这说明查询确实被分配到了不同从库。
4. 分库分表深度实践
4.1 分片策略选择
电商订单表我们最终采用了MOD_HASH算法:
CREATE TABLE orders ( id BIGINT PRIMARY KEY, user_id INT NOT NULL, amount DECIMAL(10,2) ) ENGINE=InnoDB dbpartition BY MOD_HASH(user_id) dbpartitions 8 tbpartition BY MOD_HASH(user_id) tbpartitions 32;这样设计使得同一个用户的订单总会落在同一张物理表,避免跨库查询。分片字段选择有讲究:
- 用户ID适合哈希分片
- 时间字段适合范围分片
- 地域字段适合列表分片
4.2 全局ID生成方案
MyCat 2默认使用雪花算法生成分布式ID。有次我们遇到个坑:系统时间被运维同学回拨,导致ID重复。解决方案是:
// 在sequence配置中增加workerId { "clazz":"io.mycat.plug.sequence.SnowflakeSequence", "workerId":123, "dataCenterId":1 }如果要用MySQL自增ID,记得在建表时去掉AUTO_INCREMENT关键字,否则MyCat会优先用自己的序列。
5. 高可用架构设计
5.1 双主双从集群
生产环境建议至少部署两个写入节点:
/*! mycat:createCluster{ "clusterType":"MASTER_MASTER", "masters":["master1","master2"], "replicas":["slave1","slave2"], "switchType":"SWITCH", "name":"ha_cluster" }*/;关键参数说明:
- heartbeatTimeout:心跳超时时间(ms)
- maxRetryCount:最大重试次数
- slaveThreshold:从库延迟阈值(s)
5.2 故障转移测试
模拟主库宕机:
- 停止master1容器
- 观察日志:
tail -f logs/wrapper.log - 验证写入是否自动切换到master2
有个重要发现:MyCat的故障检测存在30秒左右的延迟,所以业务层最好自己实现重试机制。
6. 性能优化实战
6.1 连接池配置
在datasource配置中调整:
{ "maxCon": 500, "minCon": 10, "maxRetryCount": 3, "idleTimeout": 600000 }建议根据实际压力测试调整:
- 连接数不是越大越好,我们测试发现300左右QPS最高
- 空闲超时建议10分钟,避免频繁重建连接
6.2 SQL拦截优化
通过firewall.json配置SQL白名单:
{ "whiteHosts": ["192.168.1.%"], "blacklist": [ { "sql": "select \\* from users", "reason": "禁止全表扫描" } ] }这个功能帮我们拦截了好几次慢查询,特别是没有带where条件的select *。
7. 踩坑经验分享
去年迁移生产环境时遇到个诡异问题:分片表JOIN查询结果不全。后来发现是因为两个表的拆分规则不一致。解决方案是:
- 确保关联表使用相同的分片键
- 或者使用全局表(small表广播)
另一个内存泄漏问题:长时间运行后MyCat内存占用越来越高。通过JVM参数调整解决:
# 在bin/mycat中添加 JAVA_OPTS="-Xms2G -Xmx2G -XX:+UseG1GC"最后建议做好监控,我们集成了Prometheus收集以下指标:
- 连接数
- 请求QPS
- 分片查询耗时
- 节点健康状态