我见过很多团队在数据库上栽跟头的方式:不是CPU突然打满,而是连接数先爆,几百个请求全部卡在“获取连接”上,一查慢日志,绝大部分就是几条简单的SELECT。这种场景下,很多人第一反应是加缓存、加索引,但真正该做的往往是先搭一套MySQL主从复制,把读流量从主库上剥离开。
这也就是“MySQL主从复制与读写分离”这套组合存在的意义:主库专心处理写请求,从库分担读请求,再配合复制延迟监控、故障切换预案,整个系统扛读的能力能上一个量级,而且架构成本并不高。这篇内容我会从复制原理讲起,用Docker给你搭一套可复现的MySQL 8.0主从环境,再讲应用层怎么写路由才能让读写真正分离,最后把主从延迟、数据一致性、故障切换这些生产里绕不开的问题一次说透。
1. 单库扛不住读的时候,为什么要引入主从复制?
1.1 先想清楚“读写分离”到底解决什么问题
绝大多数业务系统是典型的读多写少。用户在浏览商品、刷文章、查订单,真正产生写入的只有下单、评论、支付回调这些动作。如果这些读SQL全部压在同一台MySQL上,即使每一条都走了索引,连接数也会先成为瓶颈,因为一条查询无论多快,都要占用一个连接、一份内存、一部分CPU时间片。
主从复制的第一个价值,就是让读流量可以从主库“溢出”到从库。主库继续负责写,从库接受大部分读请求,主库的连接压力和IO负载立刻降下来。这个收益不是靠优化SQL能换来的,因为SQL优化解决的是单条查询的效率,而读写分离解决的是“查询总量超过单实例承载能力”的问题。
第二个价值容易被忽略:它把“备份”和“分析”这类重活从主库上摘出去了。很多团队会在凌晨用主库直接跑报表或做全量备份,主库的IO和CPU瞬间飙高,白天业务峰值时的性能其实已经被这种夜间任务影响了。有了从库,备份、离线分析、数据抽取这些操作可以全部打到从库上,不影响主库的在线业务。
第三,它才构成高可用的基础。没有副本的主库宕机,数据库恢复时间取决于磁盘和备份策略;有了从库,就有了“把流量切到副本”的可能性,虽然这需要配套的切换工具,但至少架构上不再是单点。
1.2 这套方案不是万能的,边界要提前划清楚
我经常看到团队把主从复制当成“万能药”,遇到性能问题就加从库。实际上有好几类问题主从复制解决不了。
写多读少的业务,瓶颈在主库写入能力,加从库不会让主库写得更快,反而会让主库多一份binlog推送的开销。大事务慢查询、全表扫描导致主库IO打满,从库同样会遭殃,因为从库要回放同一条SQL。需要强一致读的业务,比如用户刚下单就立刻在订单列表看到这条记录,如果读从库正好赶上复制延迟,就会出现“明明写成功了却查不到”的诡异体验,这种场景需要特殊处理。
还有一个常见误区:认为配了主从就等于高可用。实际上主库宕机后,从库不会自动顶上,必须有人或工具触发切换,应用层的连接也得跟着改。这是另一
