MySQL 读写分离中的主从延迟如何影响业务?怎么优化?
简化版
读写分离把写请求发到主库,把读请求发到从库,以分摅读压力。但主从复制存在延迟,用户刚写完马上读从库,可能读不到最新数据。优化方式包括写后读主库、按用户短时间粘主、关键查询强制读主、监控复制延迟、减少大事务和慢 SQL、提升从库并行复制能力。核心是根据业务一致性要求选择读路径。
详细版
主从延迟会造成“我刚提交的数据怎么没了”的体验问题。比如用户修改昵称后立刻刷新页面,如果读到了延迟从库,就可能显示旧昵称。
不是所有读都要强一致。商品详情、文章列表可以接受短暂延迟;支付结果、订单状态、权限变更通常要求更强一致。读写分离优化不能只看 QPS,还要看业务读一致性。
面试中要讲出写后读一致性的处理方式,这是读写分离最常见追问。
完整版教学
一、读写分离的目标
写流量集中到主库。
读流量分发到从库。
从库承担报表、列表、详情等查询。
主库压力下降。
系统读扩展能力提升。
二、主从延迟怎么产生
主库提交事务并写 binlog。
从库拉取并回放 binlog。
网络、IO、SQL 回放、锁等待都可能造成延迟。
大事务和 DDL 会放大延迟。
从库负载过高也会追不上。
三、业务影响
| 场景 | 延迟影响 | 建议 |
|---|---|---|
| 修改资料后查看 | 读到旧资料 | 短时间读主 |
| 下单后查订单 | 查不到订单 | 订单链路读主 |
| 权限变更 | 权限不一致 | 强一致读主 |
| 商品浏览 | 短暂旧数据可接受 | 可读从 |
| 报表统计 | 可接受延迟 | 从库或离线 |
四、写后读主库
用户完成写操作后。
在一个短时间窗口内把该用户读请求路由到主库。
也可以给请求上下文打标记。
关键接口直接强制读主。
这样能解决大部分写后读不一致。
写操作成功后:
user_id=1001 标记 5 秒内读主
查询路由时:
如果命中读主标记,走 master
否则按一致性等级选择 slave 或 master
实际实现可以放在网关、DAO 层或数据库访问中间件里。
五、延迟监控
要监控主从复制延迟。
延迟超过阈值时,可以减少从库读流量。
也可以让关键读自动切主。
延迟持续升高时,要定位大事务、慢 SQL、IO 和从库负载。
读写分离不是把所有 SELECT 都丢给从库,而是按一致性等级选择读路径。
六、降低延迟的手段
减少主库大事务。
避免从库执行重报表影响回放。
开启或调优并行复制。
给从库合理硬件和 IO 能力。
拆分报表从库和在线从库。
控制 DDL 和大批量更新节奏。
七、误区和追问
- 误区:读写分离后读请求都应该走从库。 强一致读和写后读通常要读主。
- 误区:主从延迟只影响体验。 权限、支付、库存等场景可能产生严重业务错误。
- 误区:加从库一定降低延迟。 从库越多不代表复制越快,还会增加运维复杂度。
- 追问:如何保证写后读一致? 粘主、读主标记、关键接口读主或等待复制位点。
- 追问:大事务为什么影响延迟? 从库回放大事务耗时长,后续事务被排队。
- 追问:从库延迟高时怎么办? 限制读流量、关键读切主、排查大事务和从库慢查询。
八、面试收束
回答时先说读写分离的扩展目标。
再讲主从延迟和写后读问题。
最后给出按一致性分级路由、监控和降低延迟的方法。