开发易掌握的知识:ShardingSphere+分库分表+读写分离

ShardingSphere 是 Apache 开源的 分布式数据库中间件,支持 分库分表、读写分离,能有效提升 数据库高并发处理能力。本文通过一个 高并发订单系统 的案例,讲解 ShardingSphere 如何实现分库分表 + 读写分离

1.分库分表

✅ 方案概述

分库分表(Database & Table Sharding)是指:

  1. 分库(Sharding Database):订单表按 user_id 进行分库,比如 user_id % 2,将数据分别存入 db_0 和 db_1
  2. 分表(Sharding Table):订单表在每个库中继续分表,比如 order_id % 4,将数据存入 order_0 ~ order_3
  3. 查询时,ShardingSphere 自动路由 SQL 到正确的数据库和表,无需应用层处理。

✅ 数据库结构

假设 2 个数据库db_0db_1),每个数据库中有 4 张订单表order_0 ~ order_3):

 

makefile

代码解读

复制代码

db_0: ├── order_0 ├── order_1 ├── order_2 ├── order_3 db_1: ├── order_0 ├── order_1 ├── order_2 ├── order_3

💡 分片规则:

  • 分库:user_id % 2 = 0 → db_0user_id % 2 = 1 → db_1
  • 分表:order_id % 4 = 0 ~ 3(4 张表)

2.读写分离

读写分离 是指:

  1. 所有写操作(INSERT, UPDATE, DELETE)走主库(Master)。
  2. 所有读操作(SELECT)走从库(Slave)。
  3. ShardingSphere 自动路由 SQL 到正确的主从库。

✅ 数据库结构

假设每个数据库 采用主从架构

 

scss

代码解读

复制代码

db_0 (主库) → db_0_slave1, db_0_slave2 db_1 (主库) → db_1_slave1, db_1_slave2

💡 读写分离策略:

  • 写入(INSERT, UPDATE) → db_0 / db_1(主库)
  • 查询(SELECT) → db_0_slave1, db_0_slave2 / db_1_slave1, db_1_slave2

3. 高并发案例:电商订单系统

📌 场景:秒杀订单

  • 业务需求:

    1. 用户下单时,订单数据写入数据库(分库分表 + 写入主库)。
    2. 订单查询时,走从库(读写分离)。
    3. 高并发支持百万 QPS,防止数据库压力过大。

✅ 代码示例(Spring Boot + ShardingSphere)

1️⃣ 配置 sharding.yml(分库分表 + 读写分离)
 

yaml

代码解读

复制代码

sharding: datasource: names: db_0, db_1 # 配置主从数据源(读写分离) master-slave-rules: db_0: master-data-source-name: db_0 slave-data-source-names: db_0_slave1, db_0_slave2 db_1: master-data-source-name: db_1 slave-data-source-names: db_1_slave1, db_1_slave2 # 分库策略(user_id % 2) sharding-rules: order: actual-data-nodes: db_${0..1}.order_${0..3} table-strategy: inline: sharding-column: order_id algorithm-expression: order_${order_id % 4} database-strategy: inline: sharding-column: user_id algorithm-expression: db_${user_id % 2}


2️⃣ 下单(写操作,分库分表 & 主库写入)
 

java

代码解读

复制代码

@Service public class OrderService { @Autowired private OrderRepository orderRepository; @Transactional public void createOrder(Long userId, Long productId) { Order order = new Order(); order.setUserId(userId); order.setProductId(productId); order.setOrderId(System.currentTimeMillis()); // 唯一 ID orderRepository.save(order); } }

💡 ShardingSphere 自动路由 SQL

  • user_id=1001,落到 db_1
  • order_id=12345,落到 order_1
 

sql

代码解读

复制代码

INSERT INTO db_1.order_1 (order_id, user_id, product_id) VALUES (12345, 1001, 567);


3️⃣ 查询订单(读操作,自动路由到从库)
 

java

代码解读

复制代码

public Order getOrder(Long userId, Long orderId) { return orderRepository.findByUserIdAndOrderId(userId, orderId); }

💡 ShardingSphere 自动路由 SQL

  • 查询 user_id=1001, order_id=12345,查询 db_1_slave1, db_1_slave2
 

sql

代码解读

复制代码

SELECT * FROM db_1.order_1 WHERE user_id = 1001 AND order_id = 12345;

💡 ShardingSphere 自动使用从库,避免影响主库性能。


4. 性能优化(支持百万 QPS)

优化点优化方式
缓存Redis 预加载热点数据(订单查询先查 Redis)。
索引优化order_id, user_id 建立联合索引,加速查询。
异步处理订单入库采用 Kafka + 异步处理,避免阻塞高并发请求。
批量插入INSERT INTO order_xxx (...) VALUES (...), (...),减少数据库连接开销。
数据库连接池配置 HikariCP 连接池,提高数据库并发处理能力。

5.事务问题

场景事务是否支持解决方案
同一 MySQL 实例(多个库)✅ 支持事务普通事务 (START TRANSACTION)
分布式数据库(多个 MySQL 实例)❌ 不支持事务Seata / ShardingSphere / 事务消息
高并发分布式架构❌ 不支持事务基于 MQ 的最终一致性
  1. 同一 MySQL 实例内,多库事务 👉 普通事务 or XA 事务(适用于小规模应用)。
  2. 分库分表,多个 MySQL 实例 👉 ShardingSphere + 读写分离(适用于电商等大规模业务)。
  3. 分布式事务(跨多个 MySQL 实例) 👉 Seata(TCC / AT 模式) 。
  4. 高并发、高可用业务 👉 RocketMQ / Kafka 事务消息(最终一致性)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值