mysql一台服务器怎么做读写分离?答案是:单机无法实现真正的读写分离,但可以通过部署主从复制架构,在同一台物理服务器上运行多个MySQL实例,再配合中间件或应用层路由,实现逻辑上的读写分离。这是中小型项目常见的过渡方案,成本低、见效快,适合并发量尚未突破单机瓶颈的业务场景,本文将给出完整实操路径,并对比不同方案的优劣,帮你少走弯路。
mysql读写分离怎么配置:单机主从复制是基础
读写分离的前提是主从复制,没有复制,从库的数据就是空谈,单机部署主从复制,本质是让一台服务器上跑两个MySQL实例,一个做主库(写),一个做从库(读),通过binlog日志保持数据同步。
单机多实例部署的两条路线
- 多端口方案:安装两份MySQL,分别占用3306和3307端口,数据目录、配置文件完全独立,这是最稳妥的方式,隔离性最好,适合生产环境。
- docker容器方案:用两个容器分别运行MySQL主从,端口映射到宿主机,优点是部署快、清理方便,适合测试环境或快速验证。
行业共识认为,单机多实例的瓶颈不在CPU而在磁盘I/O,因为两个实例共享同一块磁盘,写入竞争会放大延迟。单机读写分离适合读多写少、并发量在每秒数千级别的场景。
主从复制的核心配置步骤
第一步,编辑主库配置文件(/etc/my.cnf),开启binlog并设置server-id:
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-do-db=your_database
第二步,编辑从库配置文件,指定中继日志和只读模式:
[mysqld]
server-id=2
relay-log=mysql-relay-bin
read_only=1
第三步,在主库创建复制专用账号:
CREATE USER 'repl'@'localhost' IDENTIFIED BY 'your_password'; GRANT REPLICATION SLAVE ON . TO 'repl'@'localhost';
第四步,查看主库状态获取binlog坐标,然后在从库执行:
CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='your_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; START SLAVE;
第五步,验证复制状态:
SHOW SLAVE STATUSG
重点看两个字段:Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes,双双为Yes才算复制正常。
单机读写分离的三种落地方式对比
复制搭好了,接下来要把读写流量分开,针对单机部署,常用方案有三种,各有适用场景。
应用层双数据源方案
在代码里配置两个数据源,写操作走主库连接,读操作走从库连接,这是最直接的方式,不引入额外组件。
// Spring Boot示例
@Bean
@Primary
@ConfigurationProperties("spring.datasource.master")
public DataSource masterDataSource() { ... }
@Bean
@ConfigurationProperties("spring.datasource.slave")
public DataSource slaveDataSource() { ... }
适合小型团队、业务逻辑简单的项目,缺点是代码侵入性高,每个需要读写分离的地方都要手动指定数据源,后续维护成本会逐渐累积。
ProxySQL中间件方案
ProxySQL是一款成熟的MySQL代理层软件,支持读写分离规则配置、连接池管理、故障自动切换,单机部署时,让ProxySQL监听6033端口,后端指向本机的3306和3307端口。
核心配置只需两步:
- 在mysql_servers表中注册主从节点,weight权重可以设置读流量的分配比例
- 在mysql_query_rules表中配置规则,
SELECT语句路由到从库,INSERT/UPDATE/DELETE路由到主库
ProxySQL对应用透明,应用只需要连接一个地址,不用关心背后有几台数据库,这是目前生产环境使用较广的方案,也适合后续平滑扩展到多台服务器。
MySQL官方Router方案
MySQL Router是官方出品的轻量级中间件,配置简单,支持读写分离和故障转移,单机部署时,Router监听6446端口(读写),6447端口(只读),后端绑定本机主从实例。
mysqlrouter --bootstrap root@127.0.0.1:3306 --directory /tmp/router
启动后,应用连接6446端口即可,Router会自动识别主从角色,把写请求发给主库,读请求发给从库,官方方案的优势在于版本兼容性有保障,后续升级MySQL版本时不容易踩坑。
mysql读写分离方案对比:单机部署的核心权衡
| 对比维度 | 应用层双数据源 | ProxySQL | MySQL Router |
|---|---|---|---|
| 部署复杂度 | 低 | 中 | 中 |
| 代码侵入性 | 高 | 无 | 无 |
| 读写规则灵活性 | 中 | 高 | 中 |
| 连接池管理 | 无 | 有 | 有 |
| 故障自动切换 | 需自行实现 | 支持 | 支持 |
| 适合场景 | 小型项目 | 中大型项目 | MySQL生态用户 |
选择依据很简单:追求快速落地就选应用层双数据源,追求长期可维护性选ProxySQL,追求官方生态一致性选MySQL Router,多数情况下,ProxySQL是单机读写分离的推荐选择,因为它同时解决了连接管理和读写路由两个问题。
单机读写分离的三大坑:延迟、事务和一致性
单机部署读写分离,有几个问题比多机环境更容易踩中,需要提前设计应对方案。
主从延迟导致的读不到最新数据
同一台机器上,主从复制延迟通常只有几毫秒,但在高并发写入时,binlog同步依然可能出现短暂延迟,用户刚提交订单就去查询,可能查不到刚写入的记录。
应对方案:将必须实时读取的请求强制走主库,例如订单详情页、支付结果页;允许延迟的查询走从库,例如商品列表、搜索页面,在代码里做这个区分,比在中间件层处理更精准。
事务中的读写必须绑定主库
一个事务内如果既有写操作又有读操作,读操作必须走主库,否则事务未提交,从库读不到数据,而且读写分离到不同连接,事务隔离性会被破坏。
实操建议:在事务开始前,通过@Transactional(readOnly=false)或Hint机制将当前连接绑定到主库,事务结束后再释放。
单机部署的资源争抢问题
两个MySQL实例共享同一台服务器的CPU、内存和磁盘I/O,写操作密集时,从库的查询会受到影响,反之亦然。
缓解手段:用innodb_buffer_pool_size限制每个实例的内存占用,总分配不超过物理内存的70%;用cgroup限制实例的磁盘I/O带宽;把binlog和中继日志放在不同磁盘分区,减少写入竞争。
据行业测试数据,单机主从复制在SSD环境下可支撑每秒3000-5000次混合读写,超过这个量级就需要考虑分库分表或迁移到多机架构了。
mysql读写分离延迟问题怎么排查
主从延迟是读写分离绕不开的话题,即使单机部署,也可能因为配置不当导致延迟异常增大。
常见原因和排查路径
- 大事务阻塞:主库执行大批量UPDATE或DELETE,binlog要等事务提交才写入从库,排查方法:
SHOW PROCESSLIST查看是否有长时间运行的写事务 - 从库单线程回放瓶颈:从库SQL线程是单线程的,主库并发写入再高,从库也只能串行回放,排查方法:
中的SHOW SLAVE STATUS
Seconds_Behind_Master字段持续增大 - 磁盘I/O饱和:主从同时写同一块磁盘,I/O等待拉高,排查方法:
iostat -x 1观察%util是否接近100%
应急处理措施
临时跳过延迟:当Seconds_Behind_Master长时间不为0,且从库数据可以容忍丢失时,可以停止复制并跳过出错的事务。根治方案:启用并行复制,在从库配置slave_parallel_workers=4,让多线程并行回放不同库的事务,能明显缓解延迟。
单机读写分离适合什么业务场景
单机读写分离不是银弹,它有明确的适用边界,适合的业务画像如下:
- 读多写少:读请求占比超过80%,写请求占比低于20%
- 并发量有限:每秒总请求量在几千级别,不会出现瞬时高峰
- 数据一致性要求不极端:容忍秒级延迟,不需要强一致的实时读取
- 成本敏感:暂时没有预算增加物理服务器,但又想提升读性能
不适合的业务画像:金融交易、库存扣减、秒杀系统,这类场景对一致性要求极高,读写分离带来的延迟问题会造成资损。单机读写分离更多是过渡方案,是向分布式架构演进过程中的一个中间站。
常见问题解答
mysql一台服务器做读写分离需要什么样的硬件配置?
建议CPU至少4核以上,内存16GB起步,磁盘必须使用SSD,两个MySQL实例加上操作系统本身,资源消耗会明显高于单实例部署,如果服务器只有2核4G,强行做单机读写分离反而会因为资源争抢导致性能下降,不如直接优化单实例的查询效率。
读写分离后从库的数据能实时同步吗?
不能保证完全实时,MySQL主从复制默认是异步模式,从库存在秒级甚至毫秒级的延迟窗口,如果业务无法接受任何延迟,需要改用半同步复制(rpl_semi_sync_master_enabled=1),但会牺牲一部分写入性能作为代价。
单机读写分离和分库分表的区别是什么?
读写分离解决的是读压力大的问题,通过增加读节点分摊查询负载;分库分表解决的是数据量大和写入瓶颈的问题,通过水平拆分降低单表数据量和写入热点,两者可以结合使用,但在单机场景下,先做读写分离,后续数据量增长再考虑分库分表,是比较稳妥的演进路径。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/600686.html




