SQL读写分离需通过中间层或应用层路由控制实现写主读从,保障一致性、自动切换与业务无感;核心在于路由策略设计、业务接入改造及上线前影子流量、宕机演练和慢SQL检查。

SQL读写分离不是简单配两个数据库地址就能生效,核心在于让写操作只走主库、读操作尽量走从库,同时保障数据一致性、故障自动切换和业务无感。关键不在数据库本身,而在中间层或应用层的路由控制。
一、常见实现方式对比(选型依据)
目前主流有三类方案,适用不同阶段和团队能力:
- 代理层方案(如MyCat、ShardingSphere-Proxy、MaxScale):数据库前面加一层代理,SQL进来后由代理解析并路由。优点是业务零改造,缺点是多一跳网络、代理自身成单点(需集群部署)、复杂SQL可能解析失败。
- JDBC驱动增强(如ShardingSphere-JDBC、TDDL):替换应用的数据源驱动,在应用进程内完成路由。性能好、支持灵活策略(如强制走主库),但需升级依赖、对应用有一定侵入性。
- 应用层手动控制(Spring AbstractRoutingDataSource + AOP):完全由业务代码决定读写库,最灵活也最可控。适合中小系统或对一致性要求极高的场景,但容易误用(比如在事务中读从库导致脏读)。
二、路由策略设计要点
不能所有读都扔给从库,必须结合业务语义判断是否可读从库:
-
强一致性读必须走主库:比如用户刚提交订单,紧接着查订单详情;或任何“写后即读”场景。可通过注解(如
@Master)或线程上下文标记强制主库。 - 从库延迟容忍度要量化:监控从库复制延迟(Seconds_Behind_Master 或 GTID差值),超过阈值(如500ms)自动降级读主库,避免展示过期数据。
- 读请求打散与负载均衡:多个从库之间按权重轮询或根据响应时间动态调整,避免热点从库拖垮整体读性能。
三、业务接入关键改造项
无论选哪种技术方案,业务侧至少需明确以下几点:
-
事务边界必须清晰:Spring中
@Transactional方法内默认走主库,但若方法里混调了标@Slave的查询,可能报错或不生效——建议事务内全部操作统一走主库。 - 全局唯一ID不能依赖从库生成:自增主键、时间戳+机器号等方案必须在主库生成,否则从库回放时可能冲突。
- 缓存与数据库一致性需重审:更新后删缓存,再查时若读从库可能命中旧数据+旧缓存,形成双重误差。建议更新后主动刷新缓存,或缓存key带上主从标识。
四、上线前必做的三件事
避免“切完就炸”,验证比配置更重要:
- 影子流量验证:把线上读请求双写到新读链路,比对主从返回结果是否一致(尤其关注分页、聚合、关联查询)。
- 主库宕机演练:手动停止主库,确认写失败告警触发、读自动切到从库、且延迟监控及时上报。
- 慢SQL穿透检查:确保慢查询日志同时采集主从库,避免因从库索引缺失或统计信息陈旧导致执行计划劣化。
读写分离不是银弹,它解决的是读多写少场景下的扩展瓶颈。设计时先理清哪些读可以异步、哪些必须实时,再匹配技术方案。稳住一致性,再谈性能提升。










