数据库架构

现代系统数据库架构通常包含主从复制、读写分离、分库分表或分布式数据库。

演进路径

单机 MySQL
   │ 读压力大
   ▼
主从 + 读写分离
   │ 写压力大 / 数据量超过单机
   ▼
分库分表(ShardingSphere / Vitess)
   │ 运维复杂,跨分片查询难
   ▼
分布式数据库(TiDB / PolarDB-X)

主从复制(Master-Slave)

写请求
   │
   ▼
┌──────────┐
│  Master  │ ← 所有写操作
└────┬─────┘
     │ Binlog 复制
     │ 异步 / 半同步 / 同步
┌────┴──────────────────┐
▼                       ▼
┌──────────┐       ┌──────────┐
│  Slave 1 │       │  Slave 2 │
└──────────┘       └──────────┘
      ↑                  ↑
   读请求             读请求

复制模式:

模式说明风险
异步复制默认模式,Master 写完即返回主库宕机可能丢数据
半同步复制至少一个 Slave 收到 Binlog 才返回延迟略高
全同步复制所有 Slave 确认才返回性能差
MGR(Group Replication)多主,Paxos 协议配置复杂

读写分离实现:

  • 应用层:ShardingSphere-JDBC 拦截 SQL,自动路由读写
  • 代理层:ProxySQL / MaxScale 作为中间代理
  • K8s 内:分别创建写 Service 和读 Service 指向不同 Pod

分库分表

为什么需要

  • 单表数据量超过 1000万行时索引效率下降
  • 单机写 QPS 超过 ~5000 时成为瓶颈
  • 存储空间超过单机上限

拆分策略

垂直分库:按业务拆分(用户库、订单库、商品库)

单体数据库
   ↓ 拆分
用户库(user_db)    订单库(order_db)    商品库(product_db)

水平分表:同一业务按规则分到多张表

orders 表 → orders_0, orders_1, ..., orders_15
路由规则:user_id % 16

分片路由

路由方式说明优缺点
取模(Hash)user_id % N均匀,扩容需迁移数据
范围(Range)时间范围、ID 范围扩容方便,可能热点
一致性 Hash环形 Hash,减少迁移实现复杂
目录(Lookup)单独维护路由表灵活,多一次查询

主流方案

方案特点
ShardingSphereJava 生态,支持 JDBC 和 Proxy 两种接入方式
VitessYouTube 开源,K8s 原生,MySQL 兼容
TiDB分布式数据库,自动分片,无需改代码
PolarDB-X阿里云,MySQL 兼容,分布式事务

Vitess 架构

Application
     │
     ▼
  VTGate(SQL 路由层)
     │ 解析 SQL,路由到对应分片
     ▼
VTablet(每个 MySQL 实例的代理)
  ├── MySQL Shard 0
  ├── MySQL Shard 1
  └── MySQL Shard 2
     │
  Topology(etcd / ZK,存储分片元数据)

TiDB 架构

         ┌──────────┐
         │  TiDB    │ MySQL 协议兼容,SQL 解析层
         └────┬─────┘
              │
    ┌─────────┴─────────┐
    ▼                   ▼
┌────────┐         ┌────────┐
│ TiKV   │ ←────► │  PD    │
│ 分布式  │         │ 调度中心│
│ 存储   │         └────────┘
└────────┘
  • TiDB:SQL 层,无状态,可水平扩展
  • TiKV:分布式 KV 存储,Raft 多副本
  • PD:集群调度,负责 Region 分配和负载均衡

TiDB 特点:

  • MySQL 协议兼容,应用改动极小
  • 分布式事务(Percolator 协议)
  • HTAP:同时支持 OLTP 和 OLAP(TiFlash 列存引擎)
  • 自动分片,无需手动分库分表

分布式事务

方案一致性性能适用场景
2PC(两阶段提交)强一致不推荐,锁时间长
TCC(Try-Confirm-Cancel)强一致核心金融场景
Saga最终一致长流程业务(跨多服务)
本地消息表最终一致与 MQ 配合,简单可靠
Seata多模式支持Java 生态

本地消息表(推荐):

业务 DB(同一事务):
  INSERT INTO orders ...
  INSERT INTO local_messages (event='order.created', status='PENDING')

定时任务:
  扫描 PENDING 消息 → 发送 MQ → 更新状态为 SENT

消费方处理成功后确认

数据库选型参考

场景推荐
单机 OLTPMySQL / PostgreSQL
读多写少,高并发读MySQL 主从 + 读写分离
数据量大,需分片ShardingSphere + MySQL / TiDB / OceanBase / Vitess
HTAP(同时分析)TiDBOceanBase
PG 栈、全球多活CockroachDB
时序数据InfluxDB / TimescaleDB
文档存储MongoDB
K-V 高速Redis

Java 实战(Spring Boot / Cloud)