使用sharding-jdbc做分库分表记录
项目中要使用分库分表来解决上亿数据的存储以及查询问题,最开始使用的是硬编码的方式,根据用户id的hash值做分表,保证同一个用户落在一张表里面。后面有同事说 使用shardingsphere有现成的解决方案,于是转成了使用shardingsphere。
首先引入shardingjdbc的pom依赖
<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.1</version> </dependency>
版本比较低,主要是其他项目使用的是这个版本。
yaml配置:
server: port: 8166 spring: #多数据源 uc以及community 仅仅适用于数据同步脚本 datasource: dynamic: #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源. strict: true primary: super_community datasource: orapickup_uc: url: url username: username password: password driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource super_community: url: url_1 username: username1 password: password1 driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource orapickup_community: url: url2 username: username2 password: password2 driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource # 配置Sharding-JDBC读写分离规则 shardingsphere: # 指定数据源 dataSource: names: master,slave # 一主一从 # 配置主库数据源 master: # 必须跟上面names对应 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: url_master username: username_master password: password_master # 配置从库数据源 slave: # 必须跟上面names对应 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: url_read username: username_read password: password_read props: sql: show: true # 开启SQL显示,默认false sharding: # 默认数据源 default-data-source-name: master #读写分离 注意 分库分表的读写分离和非分库分表读写分离不同 master-slave-rules: # 在使用数据分片功能情况下,配置读写分离功能 master: # 自定义一个虚拟数据源名字,用于自动路由下方主从数据源 masterDataSourceName: master # 指定主数据源 slaveDataSourceNames: slave # 指定从数据源 loadBalanceAlgorithmType: round_robin tables: bbs_collect: #收藏表根据用户id分100张表 actualDataNodes: master.bbs_collect_$->{1..100} tableStrategy: inline: shardingColumn: create_by #shardingColumn: is_enable #分表规则:createBy hash后取模 algorithmExpression: bbs_collect_$->{Math.abs(create_by.hashCode())%100 + 1} bbs_like: #真实表#分100张表 actualDataNodes: master.bbs_like_$->{1..100} tableStrategy: inline: shardingColumn: create_by #shardingColumn: is_enable #分表规则:createBy hash后取模 algorithmExpression: bbs_like_$->{Math.abs(create_by.hashCode())%100 + 1} application: name: gwm-community-interactive-server jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 servlet: multipart: maxFileSize: 5MB maxRequestSize: 500MB gwm: mq: topics: bbsLikeTopics: bbslike-dev rocketmq: name-server: 127.0.0.1:9876 producer: group: marketing-interactive-dev
中间遇到的几个问题,首先是 分库分表和读写分离的配置问题。由于另外一个项目使用的是读写分离+多数据源,我使用了他们的那个配置,发现不行。分库分表和读写分离共用的话,需要另外配置。参考:
https://blog.csdn.net/qq_33763772/article/details/137401086
第二个是 当项目使用了事务的时候,分库分表会不生效。类似下面的格式会导致分库分表失效
@Service("bbsCollectServiceImpl") @Transactional(propagation= Propagation.REQUIRED,rollbackFor = Exception.class) todo 使用事务会导致数据源切换失效 public class BbsCollectServiceImpl implements BbsCollectService { // }