{T}

读写分离如何在业务中落地?

0. 引言

绝大多数业务是读多写少(读:写可达 10:1 甚至更高)。读写分离的核心思路:主库承接写,从库承接读,通过主从复制把写入同步到只读副本,把读压力横向摊开。它是数据库扩展的第一级台阶(比分库分表简单、成本低)。本文讲解复制原理、路由落地与主从延迟的治理。

1. 为什么需要读写分离

痛点读写分离的收益
单库连接数打满、读 QPS 高读流量分发到 N 个从库,容量线性扩展
慢查询拖垮写入分析查询(报表/统计)打到从库,主库专注 OLTP
备份/分析任务影响线上从库承担备份导出、数据仓库 ETL

2. 主从复制原理(基于 binlog)

图表渲染中…
版本复制方式说明
5.6+GTID 复制全局事务 ID,主从切换无需手动找 binlog 位点
5.7+多源复制 / 并行复制从库多线程回放,缓解延迟
8.0并行复制增强(WRITESET)、CHANGE REPLICATION SOURCE TO 新语法语句级/事务级并行,主从延迟大幅下降
sql
-- MySQL 8.0 GTID 复制配置(从库)
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='10.0.0.1', SOURCE_PORT=3306,
  SOURCE_USER='repl', SOURCE_PASSWORD='xxx',
  SOURCE_AUTO_POSITION=1;
START REPLICA;

复制异步性根源:主库提交即返回,从库异步回放——**主从延迟(Seconds_Behind_Source)**由此而来,是读写分离必须面对的问题。

3. 读写路由的两种落地方式

3.1 应用层路由(代码/框架)

java
// ShardingSphere-JDBC 示例:一主一从
spring.shardingsphere.rules.readwrite-splitting.data-sources.rw.master-data-source-name=ds-master
spring.shardingsphere.rules.readwrite-splitting.data-sources.rw.slave-data-source-names=ds-slave-0,ds-slave-1
spring.shardingsphere.rules.readwrite-splitting.data-sources.rw.load-balancer-name=round_robin
  • 优点:性能优(直连数据库)、灵活(可编程路由规则);
  • 缺点:侵入应用(引入 SDK)、多语言需各自实现。

3.2 中间件路由(代理层)

中间件说明
ProxySQLMySQL 原生代理:读写分离、连接池、故障转移,规则灵活
ShardingSphere-Proxy兼容 MySQL 协议,读写分离 + 分库分表一体
MyCat老牌中间件,读写分离 + 分片
  • 优点:应用零侵入、集中管理、多语言通用;
  • 缺点:多一跳代理(延迟 + 运维成本)、要保高可用(代理自身不能单点)。

4. 主从延迟:读写分离的头号问题

4.1 问题场景

text
用户下单成功(写主库)→ 立即查询订单(路由到从库)→ 复制未完成 → 查不到!

4.2 解决方案

方案说明适用
关键读走主库订单/支付等强一致读强制路由主库资金、订单类核心链路
延迟容忍设置读从库延迟阈值,超阈值自动切主库(ShardingSphere hint)通用
半同步复制rpl_semi_sync_source_enabled=ON:主库等至少一个从库 ack 再提交缩小延迟窗口
缓存标记写后 1s 内读缓存(Redis 写后置),避开窗口期高并发场景
并行复制调优8.0 开启 WRITESET 并行,减少从库回放延迟大事务多的系统

通用原则:能容忍延迟的读走从库,不能容忍的读走主库——路由规则要按"数据维度"配置,而不是一刀切。

5. 落地检查清单

  • 从库只读(read_only=ON,防误写造成主从不一致)
  • 监控主从延迟(SHOW REPLICA STATUS 的 Seconds_Behind_Source + 延迟告警)
  • 链路保活:从库宕机自动摘除(健康检查)
  • 复制冲突处理:从库唯一索引冲突(如重复插入)及时告警
  • 主库 binlog 保留策略(binlog_expire_logs_seconds,8.0 按秒配置)

6. 小结

  • 读写分离 = 主库写 + 从库读 + binlog 复制,是读扩展的第一级台阶;
  • 落地两种方式:应用层 SDK(ShardingSphere-JDBC)代理中间件(ProxySQL)
  • 核心问题是主从延迟:关键读走主库、半同步缩小窗口、并行复制降延迟;
  • 8.0 建议 GTID + 增强并行复制,监控延迟与复制异常是运维底线。

下一章讲解分库分表:为什么拆分、如何拆分与中间件选型。