1. 分库分表与ShardingJdbc核心概念解析
当单表数据量突破千万级时,传统的单体数据库架构就会遇到明显的性能瓶颈。我经历过一个电商平台的订单表达到3000万条记录后,即使加了索引,查询响应时间也从毫秒级飙升到秒级。这时候就需要引入分库分表技术——把数据分散到多个数据库实例和物理表中。
ShardingJdbc是Apache ShardingSphere的核心组件之一,它通过轻量级的JDBC驱动层实现分库分表逻辑,对业务代码几乎零侵入。相比传统的MyCat等中间件方案,它不需要独立部署代理服务,直接集成在应用层,性能损耗更低。
关键区别:分库是水平扩展数据库实例(如order_db1, order_db2),分表是垂直拆分单表数据(如order_0, order_1)。两者常结合使用。
2. 实战环境搭建与基础配置
2.1 依赖引入与版本选择
建议使用SpringBoot 2.7.x + ShardingJdbc 5.3.2组合,这是目前最稳定的版本搭配。Maven配置示例:
<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>5.3.2</version> </dependency>2.2 分片策略设计原则
以电商订单表为例,我们需要考虑:
- 分片键选择:通常用user_id或order_id,要保证高频查询能路由到具体分片
- 分片算法:哈希取模是最常用方式,但对扩容不友好;范围分片适合有时间序列特征的数据
spring: shardingsphere: datasource: names: ds0,ds1 ds0: # 主库配置 type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/order_db0 username: root password: 123456 ds1: # 从库配置...3. 深度分片配置实战
3.1 精确分片算法实现
自定义精确分片策略示例(按user_id的尾数分库):
public class UserIdPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> { @Override public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) { long userId = shardingValue.getValue(); int suffix = (int) (userId % 2); for (String each : availableTargetNames) { if (each.endsWith(String.valueOf(suffix))) { return each; } } throw new IllegalArgumentException(); } }3.2 分布式ID生成方案
避免使用数据库自增ID,推荐以下方案:
- Snowflake算法(默认包含在ShardingJdbc中)
- UUID(适合非连续查询场景)
- 美团Leaf等第三方服务
配置示例:
spring: shardingsphere: rules: sharding: key-generators: snowflake: type: SNOWFLAKE props: worker-id: 1234. 高级特性与性能优化
4.1 读写分离配置
结合主从复制实现读写分离:
spring: shardingsphere: rules: replica-query: >// 自定义ID生成器 public class CustomSnowflakeGenerator implements KeyGenerator { private final SnowflakeShardingKeyGenerator delegate = new SnowflakeShardingKeyGenerator(); @Override public Comparable<?> generateKey() { // 添加业务前缀 return "ORD_" + delegate.generateKey(); } }6. 监控与运维实践
6.1 集成Prometheus监控
添加依赖:
<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-agent-metrics-prometheus</artifactId> <version>5.3.2</version> </dependency>配置指标采集:
agent: metrics: prometheus: host: 0.0.0.0 port: 9090 props: "jmx_exporter_config.yaml"6.2 在线扩容方案
扩容步骤:
- 停写受影响分片
- 使用数据迁移工具(如ShardingSphere-Scaling)
- 修改分片配置并灰度发布
- 恢复写入
关键点:扩容后要更新分片算法,建议采用一致性哈希算法减少数据迁移量
我在实际项目中发现,当分片数超过16个时,连接池管理会成为瓶颈。建议每个物理库配置独立的连接池,并合理设置maxPoolSize(通常不超过CPU核心数*2)。对于高频访问的分片,可以适当增大连接数。