使用ShardingSphere分库分表

前言

本文记录ShardingSphere的学习过程、使用心得 ,ShardingSphere是一套开源分布式数据库中间件解决方案组成的生态圈,前身是当当网开源的sharding-jdbc,捐给Apache孵化成为顶级项目后,更名为ShardingSphere。

学习资料直接参考官方文档,文档十分详细,可以完整的学习ShardingSphere各组件的基础概念及使用。

->ShardingSphere官方文档

后续文章将基于springboot搭建一个ShardingSphere Demo。

依赖

创建一个Maven项目,引入spring的基本配置,在引入如下依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!-- sharding-jdbc -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- pagehelper分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

配置

spring 配置

application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
spring:
profiles:
active: sharding
main:
allow-bean-definition-overriding: true

#mybatis-plus配置
mybatis-plus:
mapper-locations: classpath:com/pace2car/shardingspheredemo/dao/xml/*Mapper.xml
typeAliasesPackage: cn.pace2car.shardingspheredemo.bean
global-config:
# 数据库相关配置
db-config:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: auto
#字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
field-strategy: not_empty
#驼峰下划线转换
table-underline: true
#数据库大写下划线转换
capital-mode: false
# 原生配置
configuration:
map-underscore-to-camel-case: true
cache-enabled: true

sharding 策略配置

application-sharding.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
sharding:
jdbc:
datasource:
names: ds0,ds1
ds0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo_ds_0?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: 123456
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo_ds_1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: 123456
config:
sharding:
# 默认指针列值生成器类类名称,缺省使用io.shardingsphere.core.keygen.DefaultKeyGenerator
# 如果自定义实现io.shardingsphere.core.keygen.KeyGenerator接口并提供无参构造方法
#default-key-generator-class-name: com.pace2car.shardingspheredemo.keygenerator.MyKeyGenerator
#executor:
#size: 4 # 工作线程数量,默认是CPU核数的两倍
# 未配置分片规则的表将通过默认的数据源定位
default-data-source-name: ds0
# 数据库分片策略
default-database-strategy:
inline:
sharding-column: tenant_id
algorithm-expression: ds$->{tenant_id % 2}
# 默认的分表策略
#default-table-strategy:
tables:
tenant:
actual-data-nodes: ds$->{0..1}.tenant
park_record:
actual-data-nodes: ds$->{0..1}.test_table_$->{0..1}
table-strategy:
inline:
sharding-column: id
algorithm-expression: test_table_$->{id % 2}
key-generator-column-name: id
#key-generator-class-name: com.pace2car.shardingspheredemo.keygenerator.MyKeyGenerator
binding-tables: tenant,test_table
props:
sql:
show: true # 显示sql
server:
port: 9090

启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.pace2car.shardingspheredemo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@ComponentScan(value = "com.pace2car")
@MapperScan(basePackages = {"com.pace2car.shardingspheredemo.dao.mapper"})
@EnableTransactionManagement(proxyTargetClass = true)
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

分表策略部署成功后,对大多数的业务并无影响,但是对涉及跨库join、复杂函数、多级不同结构的子查询等并不支持,相关的业务逻辑仍需调整。

源码涉及个人项目的敏感信息,目前在github设置了私有,希望查阅、交流的朋友可以在下方留言,我会抽时间整理一份脱敏代码开源。

后记

分库分表是目前使用较多的,在很多维度都仍有遗留问题。于运维,分表的数据迁移和数据清洗,多库的DDL操作同步问题;于开发,分布式唯一主键的生成,分表后不能跨库join,业务流程也要考虑分布式事务的问题,同时还要保证分库分表策略能够支持扩容。

目前新兴的NewSQL可以很好的解决这些问题,也有很多优秀的开源产品,如TiDB、CockroachDB等。但是对生产来说,产品的成熟和稳定才是主要目的,并且这些DB的部署成本非常高,不适合业务规模并不庞大的中小公司。

热评文章