Mycat实战:从零搭建MySQL主从复制与读写分离全攻略
1. 为什么需要MySQL主从复制与读写分离当你的应用用户量从几百涨到几万数据库查询突然变得像蜗牛一样慢页面加载转圈转得让人心焦——这就是典型的单机MySQL扛不住高并发的表现。我去年帮一个电商项目做优化他们大促时数据库CPU直接飙到100%订单提交延迟高达15秒。主从复制就像给数据库找了几个影分身主库负责处理写操作INSERT/UPDATE/DELETE从库实时同步数据并分担读操作SELECT压力。而Mycat则是智能调度员自动把写请求发给主库读请求均衡分配到各个从库。实际效果有多明显还是那个电商项目接入Mycat后查询响应时间从1.2秒降到200毫秒主库负载下降60%高峰期订单处理能力提升3倍2. 环境准备三台服务器实战配置2.1 硬件配置建议我用VMware搭建的测试环境你也可以用云服务器主库4核CPU/8GB内存/100GB SSD写操作密集从库2核CPU/4GB内存/100GB SSD读操作为主Mycat服务器2核CPU/4GB内存不需要大存储生产环境切记主从服务器硬件配置尽量一致避免性能瓶颈转移2.2 软件版本选择避坑指南踩过无数版本兼容的坑后我推荐这个稳定组合# MySQL版本主从必须一致 mysql-8.0.26 # Mycat版本 mycat1.6.7.6-release # JDK版本 openjdk-1.8.0特别提醒MySQL 8.0默认使用caching_sha2_password认证老版本Mycat连接会报错。有两种解决方案修改MySQL用户密码插件不推荐生产环境ALTER USER mycat% IDENTIFIED WITH mysql_native_password BY 123456;使用Mycat 2.0版本推荐3. MySQL主从复制步步详解3.1 主库配置关键步骤主库的my.cnf要像这样配置关键参数已加注释[mysqld] server-id 1 # 唯一ID不能与从库重复 log-bin mysql-bin # 开启二进制日志 binlog-format ROW # 最安全的复制格式 binlog-do-db order_db # 只同步业务库不同步系统库 sync_binlog 1 # 每次事务都刷盘保证数据安全重启MySQL后执行这些命令创建同步账号CREATE USER repl% IDENTIFIED WITH mysql_native_password BY Repl1234; GRANT REPLICATION SLAVE ON *.* TO repl%; FLUSH PRIVILEGES;查看主库状态时特别注意SHOW MASTER STATUS;输出中的File和Position值稍后从库配置要用到------------------------------------------------------------ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | ------------------------------------------------------------ | mysql-bin.000003 | 785 | order_db | | ------------------------------------------------------------3.2 从库配置注意事项从库my.cnf配置差异点[mysqld] server-id 2 # 必须比主库大 relay-log mysql-relay-bin read_only ON # 确保从库只读启动复制的关键命令注意替换参数CHANGE MASTER TO MASTER_HOST主库IP, MASTER_USERrepl, MASTER_PASSWORDRepl1234, MASTER_LOG_FILEmysql-bin.000003, MASTER_LOG_POS785; START SLAVE;检查复制状态一定要看到两个YesSHOW SLAVE STATUS\GSlave_IO_Running: Yes Slave_SQL_Running: Yes3.3 常见问题排查手册问题1Slave_IO_Running为Connecting检查网络连通性ping 主库IP验证账号权限在主库执行SHOW GRANTS FOR repl%问题2主从数据不一致临时解决方案跳过错误STOP SLAVE; SET GLOBAL sql_slave_skip_counter1; START SLAVE;彻底解决方案重新做主从同步4. Mycat读写分离深度配置4.1 核心配置文件拆解schema.xml示例重点看balance参数schema nameORDERDB checkSQLschemafalse sqlMaxLimit100 table nameorders primaryKeyorder_id dataNodedn1/ /schema dataNode namedn1 dataHostcluster1 databaseorder_db / dataHost namecluster1 maxCon1000 minCon10 balance1 writeType0 switchType1 heartbeatSELECT 1/heartbeat writeHost hostmaster url主库IP:3306 usermycat passwordMycat123 readHost hostslave1 url从库1IP:3306 usermycat passwordMycat123/ /writeHost /dataHostbalance参数详解0所有读发到writeHost不推荐1所有readHost和备用writeHost参与读负载推荐一主一从2随机分发所有读写适合测试3所有读随机发到readHost推荐一主多从4.2 启动Mycat的坑点记录先给MySQL创建专用账号CREATE USER mycat% IDENTIFIED BY Mycat123; GRANT SELECT,INSERT,UPDATE,DELETE ON order_db.* TO mycat%;启动命令# 控制台启动调试用 ./mycat console # 后台启动 ./mycat start如果启动失败按这个顺序查日志logs/wrapper.log启动错误logs/mycat.log运行错误logs/switch.log心跳检测日志5. 全链路验证与性能测试5.1 读写分离验证技巧在Mycat上执行这个特殊SQL-- 在主库插入服务器ID INSERT INTO orders VALUES(1, server_id); -- 在Mycat查询应该看到不同server_id SELECT * FROM orders;如果结果始终相同检查balance参数是否正确从库read_only是否开启Mycat是否配置了多个readHost5.2 性能压测对比使用sysbench进行测试# 写测试 sysbench oltp_write_only --db-drivermysql --mysql-hostMycatIP \ --mysql-port8066 --mysql-usermycat --mysql-passwordMycat123 \ --mysql-dbORDERDB --tables1 --table-size1000000 prepare # 读测试 sysbench oltp_read_only --db-drivermysql --mysql-hostMycatIP \ --mysql-port8066 --mysql-usermycat --mysql-passwordMycat123 \ --threads32 --time300 --report-interval10 run预期效果对比场景QPS平均延迟95%延迟直连主库120026ms89msMycat读写分离58005ms21ms6. 生产环境优化建议6.1 参数调优宝典Mycat关键参数conf/server.xmlproperty nameprocessorBufferPool204800/property !-- 处理线程缓冲池 -- property namedefaultSqlParserdruidparser/property !-- 使用阿里Druid解析器 -- property namesequnceHandlerType2/property !-- 分布式ID生成方式 --MySQL主库优化innodb_flush_log_at_trx_commit1 # 最安全模式 sync_binlog1 binlog_group_commit_sync_delay100 # 适当合并刷盘6.2 高可用方案推荐架构图----------------- | Keepalived | ---------------- | -------------------------------------- | | | -------------- -------------- -------------- | Mycat Proxy1 | | Mycat Proxy2 | | Mycat Proxy3 | -------------- -------------- -------------- | | | -------------------------------------- | ---------------- | MySQL Master | ---------------- | ---------------- | MySQL Slave1 | ---------------- | ---------------- | MySQL Slave2 | -----------------7. 常见故障应急方案脑裂场景处理通过show slave status确认主从延迟在延迟小的从库执行STOP SLAVE; RESET MASTER; # 提升为新的主库修改Mycat配置指向新主库Mycat内存溢出 在wrapper.conf增加wrapper.java.additional.10-Xmx2G wrapper.java.additional.11-Xms2G wrapper.java.additional.12-XX:MaxPermSize256M记得最后在从库创建相同的数据库和表结构否则复制会报错。整个搭建过程最花时间的是等待大数据量同步我遇到过500GB数据同步花了18个小时的情况这时候可以调整slave_parallel_workers参数加速。