Spring 项目中分库分表

1. 分片策略设计

分片键选择
// 示例:按用户ID分片(模10)
public class UserShardingAlgorithm implements ShardingAlgorithm<Long> {
    @Override
    public String doSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        long userId = shardingValue.getValue();
        return "user_db_" + (userId % 10);
    }
}
  • 避免热点:避免使用频繁更新字段(如订单时间戳)作为分片键
  • 业务友好:优先选择高频查询字段(如 user_id、order_id)

2. 分布式事务处理

消息队列最终一致性
// 订单服务发送退款事件
rabbitTemplate.convertAndSend("order_exchange", "refund.routing.key", 
    new OrderEvent(orderId, RefundStatus.PENDING));

// 支付服务监听退款事件
@RabbitListener(queues = "payment_refund_queue")
public void handleRefund(OrderEvent event) {
    try {
        // 执行退款操作
        paymentService.refund(event.getOrderId());
        // 更新订单状态
        orderRepository.updateStatus(event.getOrderId(), RefundStatus.SUCCESS);
    } catch (Exception e) {
        // 发送补偿消息到死信队列
        rabbitTemplate.convertAndSend("dlx_exchange", "refund.dlx.key", event);
    }
}

3. 全局唯一 ID 生成

雪花算法实现
public class SnowflakeIdGenerator {
    private final long workerId;
    private long sequence = 0L;
    
    public SnowflakeIdGenerator(long workerId) {
        this.workerId = workerId;
    }

    public synchronized long nextId() {
        // 时间戳+工作机器ID+序列号
        return (System.currentTimeMillis() << 22) | (workerId << 12) | (sequence++ & 0xFFF);
    }
}
  • 优化:预生成 ID 段减少锁竞争

4. 查询性能优化

冗余字段设计
CREATE TABLE order_info (
    id BIGINT PRIMARY KEY,
    user_id BIGINT,
    amount DECIMAL(10,2),
    status TINYINT,
    create_time DATETIME,
    // 冗余用户姓名
    user_name VARCHAR(50)
);
  • 适用场景:高频关联查询字段

5. 数据迁移方案

影子库迁移法
  1. 双写阶段:业务同时写入新旧库
  2. 校验阶段:使用工具对比数据一致性
  3. 切换阶段:逐步将流量切到新库
  4. 回滚机制:保留旧库访问通道

6. 中间件选型

ShardingSphere 集成
<!-- Spring Boot依赖 -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.3.0</version>
</dependency>

# application.properties
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.sharding.tables.order.actual-data-nodes=ds$->{0..1}.order_$->{0..3}
spring.shardingsphere.sharding.tables.order.table-strategy.standard.sharding-column=user_id
spring.shardingsphere.sharding.tables.order.table-strategy.standard.precise-algorithm-class-name=com.example.OrderTableShardingAlgorithm

7. 运维监控

关键监控指标
  • 分片键分布均衡度(如各分片数据量差异 < 10%)
  • 跨库查询占比(建议 < 5%)
  • 事务补偿重试次数
  • 慢查询 TOP10

实施建议

  1. 优先垂直分库:按业务拆分数据库(如订单库、支付库)
  2. 控制分片数量:单库分片不超过 8 个,单表数据量控制在 500 万以内
  3. 读写分离:结合主从复制提升查询性能
  4. 数据归档:定期清理历史数据(如 3 年前订单)

通过合理设计分片策略、结合中间件和消息队列,可以在保障系统扩展性的同时降低实现复杂度。实际项目中需根据 QPS、数据规模和业务特点选择合适的分库分表方案。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值