MySQL读写分离搭建,CMS大网站性能提升
当CMS网站日均访问量突破数万,单台MySQL实例的读请求会迅速吃满CPU,导致页面加载变慢甚至超时。
MySQL读写分离的核心思路是让主库只处理写操作,从库分担读请求,从而把数据库整体吞吐量提升数倍。
本文从零开始,带你完成主从复制配置、读写分离中间件搭建以及CMS程序对接,最终能通过监控确认读请求已分流到从库。
搭建前需要确认的环境与假设
以两台Linux服务器(或本机Docker容器)为例,操作系统为Ubuntu 22.04,MySQL版本选用8.0。
假设主库IP为192.168.1.10,从库IP为192.168.1.11,CMS程序使用Spring Boot + MyBatis。
如果使用宝塔面板,操作路径类似,可在软件商店安装MySQL后通过配置文件修改。
请确保主从服务器时间同步,且防火墙放行3306端口。
配置MySQL主从复制
主从复制是读写分离的基础,必须先保证从库能实时同步主库数据。
主库修改配置文件
编辑/etc/mysql/mysql.conf.d/mysqld.cnf,在[mysqld]段添加:
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = cms_db
重启MySQL:systemctl restart mysql。
然后登录主库创建复制账号:
CREATE USER 'repl'@'192.168.1.11' IDENTIFIED BY 'YourStrongPassword';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.11';
FLUSH PRIVILEGES;
查看主库状态,记下File和Position值:SHOW MASTER STATUS;
从库配置与启动复制
从库配置文件同样修改server-id = 2,并添加relay-log = /var/log/mysql/mysql-relay-bin.log。
重启后执行:
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='repl',
MASTER_PASSWORD='YourStrongPassword',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=157;
START SLAVE;
执行SHOW SLAVE STATUS\G,确认Slave_IO_Running和Slave_SQL_Running均为Yes,说明主从同步已生效。
在CMS中实现读写分离
CMS程序通常读多写少,推荐使用Spring Boot动态数据源方案,无需引入额外中间件。
添加依赖与数据源配置
在pom.xml加入:
org.springframework.boot
spring-boot-starter-jdbc
com.baomidou
dynamic-datasource-spring-boot-starter
3.5.1
在application.yml中配置主从数据源:
spring:
datasource:
dynamic:
primary: master
strict: false
datasource:
master:
url: jdbc:mysql://192.168.1.10:3306/cms_db?useSSL=false
username: cms_user
password: master_pass
slave:
url: jdbc:mysql://192.168.1.11:3306/cms_db?useSSL=false
username: cms_user
password: slave_pass
使用注解切换数据源
在Service层方法上添加@DS("slave")即可让该方法走从库:
@Service
public class ArticleService {
@DS("slave")
public List listArticles() { ... }
@DS("master")
public void saveArticle(Article article) { ... }
}
这样CMS的文章列表、评论查询等读操作自动走从库,发布、修改等写操作走主库。
宝塔面板环境下的快速操作
如果服务器安装了宝塔面板,可在软件商店安装MySQL 8.0后,通过“数据库”->“配置文件”修改上述主从参数。
主从复制部分同样需在终端执行SQL命令。
宝塔的“计划任务”可添加每分钟检查一次主从状态的脚本,便于及时告警。
验证与常见问题
搭建完成后,在从库执行SELECT * FROM cms_db.articles LIMIT 1;,能看到主库最新插入的数据即表示同步正常。
然后在CMS前端刷新页面,通过SHOW PROCESSLIST观察从库连接数是否增加。
主从延迟较大时,
可优化sync_binlog和innodb_flush_log_at_trx_commit参数,
但需权衡数据安全性。从库Slave_SQL_Running为No,
通常是因为主键冲突,
可尝试跳过错误:STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;。读写分离后数据不一致,
检查是否在写后立即读的场景强制走了主库,
Spring的@DS注解需正确切换。
结论:
MySQL读写分离搭建的关键在于主从复制稳定,
再用动态数据源将读请求导向从库,
CMS大网站性能提升效果通常在读多写少的场景下最明显。 若从库延迟持续高于1秒,
需先排查主库写入压力或网络带宽。
常见疑问
从库可以只同步部分表吗? 可以,在主库配置binlog_do_db指定数据库,或使用replicate-wild-do-table在从库过滤。
读写分离后还需要缓存吗? 建议配合Redis缓存热点数据,进一步降低从库读压力。
一主多从如何配置? 从库配置中修改server-id为不同值,并指向同一主库即可。
按照以上步骤操作后,建议通过监控工具观察主从库的QPS变化,通常从库读QPS会显著上升,主库写QPS保持稳定,此时CMS大网站性能提升的目标就已达成。