当单机数据库撑不住数据量与吞吐,传统做法是分库分表——但业务复杂度随之爆炸:跨分片 JOIN 受限、分布式事务难做、扩缩容要人工迁移。分布式数据库(NewSQL)的目标是:像单机数据库一样好用,却有水平扩展与高可用的能力。TiDB、Spanner、CockroachDB 是三大代表。本指南讲透它们如何用共识算法 + 分布式事务,把"关系型体验"搬到分布式架构上。
关键概念:NewSQL = 拥有关系型数据库的 SQL 能力与事务保证,同时具备分布式系统的水平扩展与高可用。核心组件:分布式存储(数据分片 + 多副本 + 共识)、分布式事务(跨分片提交,多版本并发控制 MVCC + 两阶段提交 2PC)、元数据调度(数据分布与故障恢复)。
一、为什么需要分布式数据库
1.1 单机数据库的瓶颈
单机关系型数据库的三大瓶颈:
1. 容量:单机磁盘/内存有上限
2. 吞吐:单机 CPU/IO 有上限
3. 高可用:单机故障=服务中断(需主备)
应对演进:
- 读写分离:解决读扩展,写仍是单点
- 分库分表:解决容量,但引入分布式复杂性
- 分布式数据库:在「数据库内部」解决扩展与高可用
→ 应用层无需关心分片,像用单机库一样用
1.2 分库分表 vs 分布式数据库
| 维度 | 分库分表中间件(Sharding) | 分布式数据库(NewSQL) |
|---|---|---|
| 分片透明 | 应用/中间件层处理,SQL 受限 | 数据库内部处理,SQL 基本透明 |
| 跨片查询 | JOIN/聚合受限 | 支持(分布式执行) |
| 分布式事务 | 需引入方案 | 内置(分布式事务) |
| 扩缩容 | 人工迁移,复杂 | 自动/在线扩缩容 |
| 高可用 | 依赖中间件+数据库主备 | 副本+共识,自动故障恢复 |
| 成本 | 较低,可控 | 较高(资源开销大) |
ℹ️ 核心:分库分表把复杂度留给上层,NewSQL 把复杂度消化在数据库内部。数据量与并发大到一定程度,NewSQL 是更省心的选择。
二、TiDB:中国开源的 HTAP 分布式数据库
TiDB 是 PingCAP 开源的分布式数据库,架构上完全解耦计算与存储。
2.1 架构总览
TiDB 三组件:
TiDB Server(计算层):
- 无状态,SQL 解析/优化/执行
- 可水平扩展(加 TiDB 节点提升并发)
TiKV(存储层):
- 分布式 KV 存储,数据按 Region 分片
- 每个 Region 多副本,Raft 共识保证强一致
- 支持 MVCC(多版本并发控制)
PD(Placement Driver,调度层):
- 管理 Region 分布、负载均衡、故障恢复
- 类似 Raft 集群的大脑
TiFlash(可选):
- 列式存储副本,承担分析查询 → 支持 HTAP
2.2 数据分片与一致性
Region(数据分片):
- 数据按 Key 范围切成 Region(默认 96MB)
- 每个 Region 3 副本(默认),副本间 Raft 复制
- Region 太大/太热 → PD 自动分裂/调度
强一致:
- 写入需多数派副本确认(Raft)
- 任意副本丢失 → 自动补副本,不丢已提交数据
- 读写都走 Raft Leader,读也强一致(除非走 Follower 读)
水平扩展:
- 加 TiKV 节点 → PD 把部分 Region 迁移过去
- 数据与负载自动均衡,应用无感知
2.3 分布式事务:MVCC + 2PC
TiDB 的分布式事务基于 Percolator 模型(Google 论文),用 MVCC 快照 + 两阶段提交实现跨 Region 事务。
TiDB 事务模型(简版):
1. 事务内读写走 Snapshot(MVCC 快照隔离)
2. 提交时两阶段提交(2PC):
Prewrite 阶段:
- 选取一个主键(Primary Key)作为协调者
- 各 Region 对涉及 Key 做 Prewrite(锁 + 预写数据)
Commit 阶段:
- 提交主键(写 Commit 标记)
- 提交其余从键
3. 崩溃恢复:若主键已提交 → 其余也提交(事务保证)
隔离级别:
- 默认 Snapshot Isolation(快照隔离)
- 支持 Serializable(通过 Leader/提交优化)
→ 业务上基本等同于可重复读
三、Google Spanner:TrueTime 与外部一致性
Spanner 是 Google 的全球分布式数据库,以全球一致性著称,秘诀是 TrueTime 时钟。
3.1 架构与特点
Spanner 关键特点:
- 全球多数据中心(异地多活)
- 数据按表/主键分区(Tablet),跨区域复制
- 使用 Paxos 组做副本一致
- 支持 SQL 与外部一致性(External Consistency)
核心:外部一致性
- 事务提交顺序 = 全局真实时间顺序
- 读操作能读到「所有在它之前提交的事务」的结果
→ 分布式系统最严格的时序保证
3.2 TrueTime:用原子钟解决时钟问题
分布式系统最难的问题之一是「时钟」:
各机器时钟不同步 → 无法判断「哪个先发生」
锁/事务靠时钟判断顺序 → 时钟漂移导致顺序错误
TrueTime(TT):
- 用 GPS 原子钟 + 数据中心时钟,提供「时间区间」
- 系统给出一个区间 [earliest, latest]
真实时间必然落在区间内
- 事务提交时记录 TT 区间,比较区间即可判序
→ 即使时钟有误差,用区间保证「不会判错先后」
意义:
- 实现外部一致性(读已提交、事务全序)
- Spanner 因此能做「跨区域强一致 + 全球事务」
ℹ️ 核心:Spanner 用 TrueTime 把「时钟不确定」变成「区间确定」,从而在分布式环境下做出"真实时间顺序"的强一致决策。这是其他分布式数据库难以复制的工程成就。
四、CockroachDB:纯 Raft 的云原生分布式 SQL
CockroachDB 是开源分布式 SQL 数据库,设计哲学是"事务串行化 + 透明分片"。
4.1 架构与事务
CockroachDB 架构:
- 无独立协调者,所有节点平等(P2P 风格)
- 数据按 Key 范围分片(Range),每 Range 3 副本
- 副本用 Raft 复制,Leader 承担读写
事务模型:
- 默认 Serializable(串行化,最严格隔离级别)
- 基于「写偏斜检测 + 冲突重试」实现串行化
- 跨 Range 事务用并行提交优化(减少 2PC 延迟)
- 支持分布式事务、事务重试(自动 retry)
串行化的代价:
- 高冲突场景下重试多、性能下降
→ 设计时注意热点 Key 与写冲突
4.2 与 TiDB 对比
| 维度 | TiDB | CockroachDB |
|---|---|---|
| 存储 | TiKV(自研,MVCC+Raft) | 自研 Range+Raft |
| 计算 | TiDB 无状态计算层 | 计算与存储混合节点 |
| 默认隔离 | Snapshot Isolation | Serializable |
| 调度 | PD 中心化调度 | 无中心(去中心化) |
| 生态 | MySQL 协议兼容 | PostgreSQL 协议兼容 |
| HTAP | TiFlash 列存 | 有限(支持列索引) |
选型要点:
- 团队用 MySQL 协议 → 选 TiDB(兼容好、生态成熟)
- 团队用 PostgreSQL 协议 → 选 CockroachDB
- 需要 HTAP(事务+分析同库)→ TiDB + TiFlash
- 需要去中心化部署 → CockroachDB
五、分布式事务与隔离级别
分布式数据库的事务保证是"能不能替代单机数据库"的关键。
5.1 隔离级别对比
分布式数据库常见隔离级别:
- Read Committed:读已提交,可能有不可重复读
- Snapshot Isolation:快照隔离,读一致快照
- Serializable:串行化,最严格(代价是性能)
TiDB:Snapshot Isolation(可重复读级)
Spanner:外部一致性(读已提交之上更强时序)
CockroachDB:Serializable(串行化)
注意:
- SI 在分布式下也存在「写偏斜」问题
- 需要严格串行化语义时选 Serializable 方案
- 高并发写冲突场景,串行化会放大重试成本
5.2 跨分片查询
分布式数据库的 SQL 能力:
- 跨 Region/分片 JOIN、聚合 → 分布式执行
- 全局唯一索引(跨分片唯一约束)
- 分布式查询优化器(代价估算、分片下推)
限制与注意:
- 跨分片事务比单机事务慢(网络往返 + 2PC)
- 大量跨分片小事务 → 性能明显下降
→ 设计表与主键时尽量「同分片聚合」相关数据
六、一致性与性能的权衡
分布式数据库并非银弹,它的能力与代价都需要清醒认识。
能力:
- 水平扩展:数据与负载可随节点增加而扩展
- 高可用:多副本自动故障恢复,RTO 秒级
- 强一致:事务与读写都有严格的保证
代价:
- 延迟:跨副本共识 + 分布式事务 → 单机库更慢
- 资源:多副本存储 ×3,计算冗余
- 复杂度:参数调优、热点治理、故障排查更难
适用场景:
数据量/吞吐超过单机库上限,或需要极高可用
- 电商订单、用户中心、金融核心账务
- HTAP 一体(写事务 + 读分析同库)
不适用:
读写都小、延迟极度敏感(<1ms)且单机够用
→ 不要为「用新而新」,单机库 + 合理架构仍是最优
ℹ️ 核心:分布式数据库解决的是"规模与可用性",代价是"延迟与资源"。规模没到瓶颈时,单机数据库 + 读写分离/分库分表可能是更经济的选择。
七、生产实践与常见避坑
7.1 生产实践要点
TiDB 生产实践:
- 合理设计主键,让相关数据落在同一 Region(同分片聚合)
- 避免热点:自增主键打散写入热点,或用 hash 分区
- 监控 Region 热点与 Leader 分布,及时调整
- 大事务/大批量导入拆小,避免 2PC 放大
- 备份、监控、告警按数据库标准建设
Spanner/CockroachDB 实践:
- 评估跨区域延迟对事务的影响
- 串行化高冲突场景注意重试与热点
7.2 常见避坑
| 坑 | 现象 | 对策 |
|---|---|---|
| 主键设计不当 | 写入热点集中在少数 Region | hash/合理主键打散 |
| 大事务 | 2PC 延迟高、锁冲突 | 拆小事务、批量分批 |
| 热点 Key | 单 Region 性能瓶颈 | 热点打散 + 监控调度 |
| 跨片小事务过多 | 性能远低于预期 | 数据同分片聚合 |
| 当单机库用 | 忽略分布式调优 | 按分布式规则设计 |
| 无备份演练 | 数据丢失无法恢复 | 定期备份 + 恢复演练 |
八、最佳实践清单
□ 先评估规模是否真的需要分布式数据库
□ 选型看协议兼容(MySQL→TiDB,PG→CockroachDB)
□ 主键与分片设计让相关数据同分片聚合
□ 打散写入热点,监控 Region 分布与 Leader 热点
□ 大事务拆小,控制单事务跨分片数量
□ 理解默认隔离级别,需要时选 Serializable
□ 按数据库标准做备份、监控、告警、恢复演练
□ 从单机库迁移时做充分的功能与性能验证
一句话原则
分布式数据库 = 共识复制 + 分布式事务 + 自动调度,
用「延迟与资源的代价」换「水平扩展与高可用」,规模到了才值得。
小结
分布式数据库(NewSQL)把"扩展性与高可用"消化在数据库内部,让应用层像用单机关系库一样使用。TiDB 以解耦的计算/存储架构 + MVCC + Percolator 两阶段提交提供 MySQL 协议的 HTAP 能力;Spanner 用 TrueTime 原子钟实现全球外部一致性;CockroachDB 以纯 Raft 去中心化实现 PostgreSQL 协议的串行化事务。落地记住五件事:先评估规模再上、选型看协议兼容、主键分片同片聚合、打散写入热点、理解隔离级别与分布式代价。当数据量超过单机瓶颈、且业务需要事务保证与自动高可用时,分布式数据库就是比"分库分表+自维护事务"更省心的下一站。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。