0
0
0
0
博客/.../

什么是数据库读写分离?TiDB 智能路由 vs 传统代理方案对比

 Billmay表妹  发表于  2026-06-02
原创

摘要

读写分离是提升数据库吞吐量和降低主库压力的经典架构模式。本文从概念原理出发,对比传统 MySQL 主从 + 中间件代理方案与 TiDB 原生智能路由方案的优劣差异,帮助架构师和 DBA 选择适合业务的读写分离策略。本文适合后端架构师、DBA、技术负责人及对数据库架构选型感兴趣的开发者阅读。


一、读写分离的概念与价值

1.1 什么是读写分离

读写分离(Read/Write Splitting)是指将数据库的写操作路由到主节点(Primary),将读操作分散到多个从节点(Replica)的架构模式。其核心目标是:

  • 提升读吞吐:通过增加只读副本数量水平扩展读能力
  • 降低主库压力:将查询请求分流,避免主库成为瓶颈
  • 优化用户体验:读请求就近路由到最近副本,降低网络延迟

1.2 典型应用场景

场景 读/写比 读写分离收益
电商商品详情页 100:1 显著,读副本可承载绝大部分流量
社交信息流 50:1 高,关注列表/消息列表均为读密集
ERP/CRM 系统 10:1 中等,报表查询可分流到从库
金融交易系统 3:1 有限,强一致性要求高,读延迟敏感

根据业内统计,大多数在线业务系统的读写比在 5:1 到 100:1 之间,读写分离在大多数场景下都能带来明显收益。


二、传统读写分离方案

2.1 架构概述

传统方案基于 MySQL 主从复制架构,通过中间件代理实现读写路由:

应用层
  │
  ▼
代理层(ProxySQL / MyCat / ShardingSphere-Proxy)
  ├── 写请求 ──► MySQL Primary(主库)
  └── 读请求 ──► MySQL Replica × N(从库)
                     ▲
                     │  binlog 异步复制
                     └── MySQL Primary

2.2 主流中间件对比

中间件 优势 劣势
ProxySQL 轻量、高性能(C++ 实现)、查询缓存 配置复杂,社区版功能受限
MyCat 功能丰富,支持分库分表 性能开销较大,维护活跃度下降
ShardingSphere-Proxy Java 生态友好,Apache 基金会项目 Java 运行时资源消耗相对较高
MySQL Router Oracle 官方出品,配置简单 功能较基础,适合简单场景

2.3 传统方案的核心问题

数据延迟:主从复制基于 binlog 异步同步,从库数据存在毫秒到秒级延迟。在写入后立即读取的场景中,可能出现读到旧数据的问题。

运维复杂度:需额外维护代理层,包括代理的高可用部署、配置变更、故障切换等。代理层本身成为新的故障点和运维负担。

连接管理:应用与数据库之间多了一跳网络,增加延迟的同时也增加了连接管理的复杂度。

-- 传统方案中处理主从延迟的常见做法
-- 方式 1:强制走主库
SET @read_from_primary = 1;  -- 需代理层支持

-- 方式 2:等待延迟消除
SELECT MASTER_WAIT(1000);  -- 等待最多 1 秒

三、TiDB 智能路由方案

3.1 架构原理

TiDB 采用计算-存储分离架构,天然具备读写分离能力,且无需额外中间件:

应用层
  │
  ▼
TiDB Server(计算节点,无状态,可水平扩展)
  │
  ▼
PD Server(元数据管理 + 调度)
  │
  ├── TiKV Leader ──► 写请求
  └── TiKV Follower ──► 读请求(智能路由)

3.2 Follower Read(跟随者读)

Follower Read 允许 TiDB 将一致性读请求路由到 Raft Follower 节点,大幅提升读吞吐能力:

-- 使用 Follower Read(需指定近似时间戳或 GC 安全点内的时间)
SELECT * FROM orders WHERE region = '华东'
AS OF TIMESTAMP '2026-01-15 10:00:00';

-- 开启自动 Follower Read(默认关闭)
SET SESSION tidb_read_staleness = '-10';  -- 读取 10 秒前的数据

核心特性

特性 说明
无额外组件 无需代理层或中间件,TiDB 原生支持
一致性保证 基于 Raft 一致性协议,确保读到已提交数据
自动路由 PD 调度器自动选择最优副本读取
弹性扩展 增加 TiKV 节点即可提升读吞吐,自动均衡

3.3 Stale Read(旧数据读)

Stale Read 是 TiDB 5.4+ 版本推出的更简便的读取模式:

-- 设置读时间窗口(相对于当前时间)
SET SESSION tidb_read_staleness = '-5';  -- 允许 5 秒内的旧数据

-- 之后的 SELECT 自动路由到 Follower
SELECT COUNT(*) FROM orders WHERE create_time > '2025-01-01';

Stale Read 与 Follower Read 的关键区别:

维度 Follower Read Stale Read
配置方式 SQL 级别指定时间戳 Session 级别设置时间窗口
适用版本 TiDB 3.0+ TiDB 5.4+
使用便捷性 需要传入具体时间戳 设置一次,后续查询自动生效
典型场景 报表查询、批处理 实时性要求不高的业务查询

四、TiDB vs 传统方案对比

4.1 综合对比

维度 传统 MySQL + Proxy TiDB 智能路由
架构复杂度 高(需维护代理 + 主从) 低(原生内置,无需中间件)
数据延迟 毫秒-秒级(异步复制) 可控(基于 Raft,时间戳精确)
一致性保证 最终一致性 强一致性(Raft 协议)
运维成本 高(代理 HA、配置管理) 低(自动调度,零配置)
弹性扩展 需手动增加从库 增加 TiKV 节点,自动均衡
故障自愈 需人工或 MHA 自动切换 Raft 自动选举,秒级恢复
读写切换逻辑 代理层硬编码 无需切换,统一 SQL 接口

4.2 性能对比参考

在 TiDB 官方测试中(TPC-C 1000 Warehouse 场景):

方案 读 QPS 写 TPS P99 读延迟
MySQL 单主 ~50,000 ~10,000 3ms
MySQL + 3 从库 + ProxySQL ~150,000 ~10,000 5ms(含代理开销)
TiDB 3 TiDB + 9 TiKV ~400,000 ~10,000 2ms

TiDB 通过多副本并行读取和自动路由,在保持写性能的同时将读吞吐提升 8 倍。


五、读写分离最佳实践

5.1 TiDB 读写分离实践建议

-- 1. 连接池配置:读写分离场景建议增大连接池
-- Spring Boot 配置示例
spring.datasource.hikari.maximum-pool-size=50

-- 2. 将报表/分析查询路由到 Follower
SET SESSION tidb_read_staleness = '-30';
-- 执行报表查询...

-- 3. 关键业务保持默认(Leader Read),确保最新数据
-- 无需额外配置,默认即走 Leader

5.2 不适合读写分离的场景

  • 强一致性要求高的金融交易(写入后必须立即读到最新值)
  • 实时库存扣减(超卖敏感场景)
  • 实时消息推送(写入后必须立即可见)

这些场景下建议保持 Leader Read,TiDB 的分布式架构本身已能提供足够高的吞吐量。

5.3 从传统方案迁移到 TiDB 的建议

  1. 评估读写比:分析业务实际读写比,确定读写分离的实际需求
  2. 灰度切换:先将低风险业务的读流量切换到 Follower Read,验证效果
  3. 逐步下线代理:确认 Follower Read 稳定后,移除 ProxySQL 等中间件
  4. 监控对比:在切换前后对比延迟、吞吐、错误率等指标

六、总结

读写分离是提升数据库读吞吐量的有效手段。传统方案通过中间件代理 + 主从复制实现,但带来了运维复杂度和数据延迟问题。TiDB 基于计算-存储分离和 Raft 一致性协议,提供了无中间件、强一致性的原生读写分离方案,大幅降低了架构复杂度和运维成本。对于读写比高、读性能有要求的业务,TiDB 的 Follower Read 和 Stale Read 是更现代、更简洁的选择。


下一步行动

  • 试用 TiDB Follower ReadTiDB Cloud 免费试用 — 免费创建 TiDB Serverless 集群,体验原生读写分离
  • 下载 POC 测试环境TiUP 部署文档 — 使用 TiUP 快速部署测试集群,验证读写分离效果
  • 阅读 TiDB 读写分离技术文档Follower Read 文档 — 了解 Follower Read 的完整技术细节

常见问题(FAQ)

Q1:TiDB Follower Read 会有数据延迟吗?

Follower Read 的延迟取决于 Raft 复制延迟,通常在毫秒级。通过 `tidb_read_staleness` 设置时间窗口后,TiDB 保证读到的时间戳之前的数据一定是完整且一致的。用户可根据业务对延迟的容忍度灵活设置时间窗口。

Q2:Follower Read 会增加 TiKV 的负担吗?

TiKV 节点本身已存储全量数据副本,读请求路由到 Follower 不会增加存储开销。但会增加 Follower 的 CPU 和 I/O 负载,建议根据实际负载监控各节点的资源使用情况。TiDB 的 PD 调度器会自动均衡读流量。

Q3:TiDB 的读写分离需要修改应用代码吗?

Stale Read 只需在 Session 级别设置一次 `tidb_read_staleness`,后续所有 SELECT 自动路由到 Follower,对应用代码几乎无侵入。如不设置,默认走 Leader Read,完全兼容现有 MySQL 应用。

Q4:读写分离方案如何与事务配合?

在事务中,所有读操作默认走 Leader 以保证事务一致性。如需在事务中使用 Follower Read,需注意隔离级别的影响。建议对一致性要求不高的大范围查询(如报表、统计)使用 Follower Read,关键事务保持 Leader Read。

Q5:TiDB 支持跨地域读写分离吗?

TiDB 支持 Placement Rules,可将 Follower 副本放置在异地机房,实现就近读取。结合 TiCDC 跨地域同步或 TiDB 的跨数据中心部署方案,可实现全局读写分离架构,降低跨地域访问延迟。


相关资源

0
0
0
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论