垂直分片
按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。
水平分片
水平分片又称为横向拆分。 相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分。
垂直分库
在resources
目录下新建vertical-db-sharding-config.yml
配置文件,存放ShardingSphere
数据源、分片规则等配置信息。
在application.yml
文件中指定YAML
配置文件:
server:
port: 8084
spring:
datasource:
# 配置 DataSource Driver
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
# 指定 YAML 配置文件
url: jdbc:shardingsphere:classpath:vertical-db-sharding-config.yml
vertical-db-sharding-config.yml
配置文件中添加用户库、订单库数据源:
dataSources:
# 用户库
ds_user: # 逻辑名称
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.101:3308/user
username: root
password: "root"
# 订单库
ds_order:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.101:3306/order
username: root
password: "root"
hikari:
minimum-idle: 10
idle-timeout: 60000
maximum-pool-size: 12
auto-commit: true
max-lifetime: 120000
connection-timeout: 60000
首先需要添加数据分片规则标识!SHARDING
:
# 规则配置
rules:
# 标识为数据分片规则
- !SHARDING
完整配置为:
# 规则配置
rules:
# 数据分片规则
- !SHARDING
# 分片表
tables:
# 逻辑表名称
t_order:
# 数据节点,数据源名称,多个以逗号分隔,默认使用全部配置的数据源
actualDataNodes: ds_order.t_order
t_user:
actualDataNodes: ds_user.t_user
tables
可配置属性说明:
名称 | 数据类型 | 说明 | 默认值 |
---|---|---|---|
logicTable | String | 分片逻辑表名称 | - |
actualDataNodes (?) | String | 由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持行表达式 | 使用已知数据源与逻辑表名称生成数据节点,用于广播表或只分库不分表且所有库的表结构完全一致的情况 |
databaseShardingStrategy (?) | ShardingStrategyConfiguration | 分库策略 | 使用默认分库策略 |
tableShardingStrategy (?) | ShardingStrategyConfiguration | 分表策略 | 使用默认分表策略 |
keyGenerateStrategy (?) | KeyGeneratorConfiguration | 自增列生成器 | 使用默认自增主键生成器 |
auditStrategy (?) | ShardingAuditStrategyConfiguration | 分片审计策略 | 使用默认分片审计策略 |
水平分库
在resources
目录下新建level-db-sharding-config.yml
配置文件,存放ShardingSphere
数据源、分片规则等配置信息。
在application.yml
文件中指定YAML
配置文件:
server:
port: 8086
spring:
datasource:
# 配置 DataSource Driver
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
# 指定 YAML 配置文件
url: jdbc:shardingsphere:classpath:level-db-sharding-config.yml
vertical-db-sharding-config.yml
配置文件中添加订单库数据源:
# 数据源配置
dataSources:
# 订单库1
ds_order_0: # 逻辑名称
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.101:3308/order
username: root
password: "root"
# 订单库2
ds_order_1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.101:3306/order
username: root
password: "root"
分片规则配置
数据节点
当前指数据表在每个数据源内呈现均匀分布的态势:
ds_order_0
├── t_order
ds_order_1
├── t_order
数据节点的配置如下:
# 规则配置
rules:
# 分片规则
- !SHARDING
# 分片表
tables:
t_order: # 逻辑表名称
actualDataNodes: ds_order_0.t_order,ds_order_1.t_order # 实际数据节点,由数据源名 + 表名组成
上述数据节点配置一旦节点很多,就很繁琐,不易阅读,不易维护,这时可以使用行表达式,解决配置的简化与一体化问题,有效地简化数据节点配置工作量。 目前支持数据节点和分片算法这两个部分的配置
行表达式由两部分组成:
SPI
实现的类型名称- 表达式
例如<GROOVY>t_order_${1..3}
,GROOVY
表示 SPI
实现的类型名称,使用<>
包裹,此部分省略时,默认使用 InlineExpressionParser SPI
的 GROOVY
实现来解析表达式。 t_order_${1..3}
为此行表达式的表达式部分。
GROOVY
实现的行表达式的使用非常直观,只需要在配置中使用${ expression }
或 $->{ expression }
标识行表达式即可。行表达式的内容使用的是·Groovy· 的语法,Groovy
能够支持的所有操作,行表达式均能够支持
上述数据节点的配置可以替换为:
actualDataNodes: ds_order_${0..1}.t_order # 实际数据节点,由数据源名 + 表名组成
分片算法
在分片规则配置类YamlShardingRuleConfiguration
中, shardingAlgorithms
属性用于配置对应的数据分片算法:
public final class YamlShardingRuleConfiguration implements YamlRuleConfiguration {
private Map<String, YamlAlgorithmConfiguration> shardingAlgorithms = new LinkedHashMap();
}
shardingAlgorithms
首选需要配置一个算法名称,然后配置其类型和属性:
public final class YamlAlgorithmConfiguration implements YamlConfiguration {
// 算法类型
private String type;
// 算法属性
private Properties props = new Properties();
}
ShardingSphere
内置了多种分片算法,按照类型可以划分为自动分片算法、标准分片算法、复合分片算法和Hint
分片算法,其中标准分片算法又分为行表达式分片算法、时间范围分片算法
订单表主键ID
是单数还偶数,使用行表达式分片算法最合适。算法配置如下,ds_order_${id % 2}
表示根据ID
进行取模运算,例如插入一条ID
为1
订单数据时,表达式计算的结果为ds_order_1
。
# 规则配置
rules:
# 分片规则
- !SHARDING
# 分片算法名称和配置
shardingAlgorithms:
database_inline: # 自定义的分片算法名称
type: INLINE # 分片算法类型:INLINE(行表达式分片算法)
props: # 分片算法属性配置
algorithm-expression: ds_order_${id % 2} # 算法表达式
allow-range-query-with-inline-sharding: true # 是否允许范围查询。注意:范围查询会无视分片策略,进行全路由,默认值false
分片策略
分片策略包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。 真正可用于分片操作的是分片键 + 分片算法,也就是分片策略
在上面我们配置了算法后,需要将算法绑定到逻辑表的分片策略,对应的配置类为YamlShardingStrategyConfiguration
:
public final class YamlShardingStrategyConfiguration implements YamlConfiguration {
private YamlStandardShardingStrategyConfiguration standard;
private YamlComplexShardingStrategyConfiguration complex;
private YamlHintShardingStrategyConfiguration hint;
private YamlNoneShardingStrategyConfiguration none;
}
分库策略分为以下几种类型:
standard
:标准分片策略complex
:复合分片策略hint
:Hint
分片策略none
:不分片策略
在上面我们配置了一个标准分片算法下的行表达式分片算法,所以databaseStrategy
配置为 standard
标准分片策略,其包含了两个可配置属性:
名称 | 数据类型 | 说明 |
---|---|---|
shardingColumn | String | 分片列名称 |
shardingAlgorithmName | String | 分片算法名称 |
整个水平分库的配置如下:
# 规则配置
rules:
# 分片规则
- !SHARDING
# 分片算法名称和配置
shardingAlgorithms:
database_inline: # 自定义的分片算法名称
type: INLINE # 分片算法类型:INLINE(行表达式分片算法)
props: # 分片算法属性配置
algorithm-expression: ds_order_${id % 2} # 算法表达式
allow-range-query-with-inline-sharding: true # 是否允许范围查询。注意:范围查询会无视分片策略,进行全路由,默认值false
# 分片表
tables:
t_order: # 逻辑表名称
# actualDataNodes: ds_order_0.t_order,ds_order_1.t_order # 实际数据节点,由数据源名 + 表名组成
actualDataNodes: ds_order_${0..1}.t_order # 实际数据节点,由数据源名 + 表名组成
databaseStrategy: # 分库策略,缺省表示使用默认分库策略,分片策略只能选其一
standard: # 分片算法策略 (standard:标准的,INLINE属于standard)
shardingColumn: id # 分片列名称
shardingAlgorithmName: database_inline # 自定义的分片算法名称
水平分表
在resources
目录下新建level-table-sharding-config.yml
配置文件,存放ShardingSphere
数据源、分片规则等配置信息。
在application.yml
文件中指定YAML
配置文件:
server:
port: 8086
spring:
datasource:
# 配置 DataSource Driver
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
# 指定 YAML 配置文件
url: jdbc:shardingsphere:classpath:level-table-sharding-config.yml
level-table-sharding-config.yml
配置文件中添加订单库数据源:
# 数据源配置
dataSources:
# 订单库_偶数
ds_order_0: # 逻辑名称
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.101:3308/order
username: root
password: "root"
# 订单库_奇数
ds_order_1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.101:3306/order
username: root
password: "root"
数据节点
当前指数据表分布示意:
ds_order_0
├── t_order_0
├── t_order_2
├── t_order_4
├── t_order_6
├── t_order_8
ds_order_1
├── t_order_1
├── t_order_3
├── t_order_5
├── t_order_7
├── t_order_9
数据节点使用行表达式的配置如下:
# 规则配置
rules:
# 分片规则
- !SHARDING
# 分片表
tables:
t_order: # 逻辑表名称
actualDataNodes: ds_order_0.t_order_${[0,2,4,6,8]},ds_order_1.t_order_${[1,3,5,7,9]} # 实际数据节点,由数据源名 + 表名组成
分片算法使用行表达式分片算法,算法表达式使用id % 10
计算尾数,根据0 - 9
的尾数存入到对应的订单表中。
完整的规则配置如下:
# 规则配置
rules:
# 分片规则
- !SHARDING
# 分片算法名称和配置
shardingAlgorithms:
# 分库
database_inline: # 自定义的分片算法名称
type: INLINE # 分片算法类型:INLINE(行表达式分片算法)
props: # 分片算法属性配置
algorithm-expression: ds_order_${id % 2} # 算法表达式
allow-range-query-with-inline-sharding: true # 是否允许范围查询。注意:范围查询会无视分片策略,进行全路由,默认值false
# 分表
table_inline:
type: INLINE
props:
algorithm-expression: t_order_${id % 10}
allow-range-query-with-inline-sharding: true
# 分片表
tables:
t_order: # 逻辑表名称
actualDataNodes: ds_order_0.t_order_${[0,2,4,6,8]},ds_order_1.t_order_${[1,3,5,7,9]} # 实际数据节点,由数据源名 + 表名组成
# 分库策略
databaseStrategy:
standard: # 分片策略类型 (standard:标准的,INLINE属于standard)
shardingColumn: id # 分片列名称
shardingAlgorithmName: database_inline # 自定义的分片算法名称
# 分表策略
tableStrategy:
standard: # 分片策略类型
shardingColumn: id # 分片列名称
shardingAlgorithmName: table_inline # 自定义的分片算法名称