使用sharding-jdbc进行分库分表
本文介绍下使用sharding-jdbc进行分库分别
一、分库分表:
1、垂直分库:一个电商库,拆分成用户库、商品库、订单库、库存库
2、水平分库:一个电商库,拆分成多个电商库
3、垂直分表:一个表字段很多,拆分成2张表,常用的字段在主表,不常用的字段在从表
4、水平分表:一个表数据量很大,然后拆分到多张表存放
二、sharding Sphere 介绍
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc</artifactId>
<version>5.5.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-test-util</artifactId>
</exclusion>
</exclusions>
</dependency>
2、配置分库分表规则
① Spring Boot 主配置文件,在application.yml里面添加如下配置(注意需要将原先的单库的配置注释)
spring: datasource: driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver url: jdbc:shardingsphere:classpath:sharding.yaml
② 配置sharding.yaml文件,主要做如下的事:
配置数据库分片规则;
配置数据表分片规则;
配置主键的生成策略;
# 配置数据源
dataSources:
ds_0:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/aicloud?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true
username: root
password: root
ds_1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/aicloud2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true
username: root
password: root
# 配置分片策略
rules:
- !SHARDING
tables: # 数据分片规则配置
answer:
actualDataNodes: ds_$->{0..1}.answer
databaseStrategy:
standard: # 标准分片
shardingColumn: uid # 分片列名称
shardingAlgorithmName: alg_mod # 分片算法名称
keyGenerateStrategy: # 分片键生成策略配置
column: aid
keyGeneratorName: snowflake
discuss:
actualDataNodes: ds_0.discuss
comment:
actualDataNodes: ds_0.comment
discuss_support:
actualDataNodes: ds_0.discuss_support
user:
actualDataNodes: ds_0.user
shardingAlgorithms: # 分片算法配置
alg_mod:
type: INLINE # 分片算法类型
props: # 分片算法属性配置
algorithm-expression: ds_$->{uid % 2}
keyGenerators: # 分片键生成器配置
snowflake:
type: SNOWFLAKE # 分布式序列算法类型
上面的配置中,answer是需要进行分库分表的表,其余的表不需要的话,就参照上面的discuss表的配置,其中采用的是Uid作为分片键,需要配置主键唯一策略,采用的是雪花算法
(雪花算法:起源于冬天的雪片,没有一片是重复的,故而生成的id没有一个是重复的)
sharding的配置参照:https://shardingsphere.apache.org/document/5.1.1/cn/reference/sharding/
3、demo测试,写一个测试类:
@SpringBootTest public class ShardingJDBCTest { @Resource private IAnswerService answerService; @Test public void test() { for (long i = 0; i < 7; i++) { Answer answer = new Answer(); answer.setTitle("test"); answer.setContent("test"); answer.setModel(1); answer.setType(1); answer.setUid(i); answerService.save(answer); } } }
如果相应数据库都得到了数据的插入,说明配置无误。
以下是整理的一些关于分库分表的一些基本,可以看下:
1、通常多少数据的时候,需要进行分库分表:阿里巴巴手册规定,单表数据达到500W或者容量2G的时候最好进行分库分表。实际开发中一般不会这么小,通常超过3000W的数据的时候,才会做分库分表。但原则上查询性能收到影响了,即使加了索引和SQL优化,依然达不到理想的查询效率的时候,即可进行分库分表(分库分表场合参考上一点);而不是简单的根据单表数量去判断,因为有些结构简单的表,即使数据上亿,查询性能也不差。
2、分库分表的判断:根据实际情况判断单表的日增加量,然后预计一年的增量,那可以预估未来10年的增量,因为互联网生命周期的问题,通常不用考虑10年以后,因为如果10年以后还存在该系统或者一样保持该增量,那么就肯定有能力去进行做数据迁移 。如果每日百万数据量增加,其实一个库多个表就基本可以满足了,但如果每日千万级别的数据增加,那就需要分库。通常一个库存放256张表就基本达到这个极限,一般一个库不可能只有一张类型(比如订单表)的多张表,肯定还有别的表,那就可以将不同类型的表放到不同的库中。
3、分库和分表的场合:分库是为了解决连接数,因为单库连接数是有限的(提升吞吐量),分表是为了解决容量的问题,本质是提升查询性能
4、哪些数据需要分库分表:不是所有的表都需要做分库分表,通常核心或者重要的数据,才需要做分库分表,比如商品表、订单表等核心强的业务表;那想日志那样的表,可以考虑定期删除很久之前的(比如一年),或者使用TiDB或者ES等分布式数据库存储。
5、拆分到哪张表:可以采用用户ID、订单号取模,或者限定算法,比如时间段、地域性等,具体看业务场景,查询的时候也使用该方式进行查询(即查询方式和插入方式一致)
6、原则:能不分就尽量不分,因为分了会增加系统复杂性
7、几个关键名词:
数据分片:一张表,分到不同数据库不同表;
数据节点:当一个表拆分为每个小表;
逻辑表:就是程序在查询层面还是查询t_order;
物理表:实际数据库有三张表t_order1、t_order2、t_order3;share-jdbc会自动帮我们去查询物理表;
分片键:取模拆分的那个关键字段;
8、如何进行分库分表:
使用share-jdbc工具,引入相关依赖,做好相关分库分表规则配置,启动完成,该工具会将数据库和表创建好,也要分配好分布式ID的生成规则,尝试插入数据,可以看到相应分库分表的数据插入到对应位置,而查询的时候也会根据插入的规则,到相应的库表中查询数据,但只针对分片规则那个字段而言,如果是普通字段,会查询所有的分表。
浙公网安备 33010602011771号