学习思路
- 快速启动配置讲解
- 五种分片策略
- 四种分片算法
- 文末有git地址
一、快速启动配置讲解
1、引入jar包
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC2</version>
</dependency>
2、执行spring-cloud-example\sharding-sphere\script目录下sql
3、配置数据源、分片字段、规则等
本文基于mysql
spring:
shardingsphere:
datasource:
names: ds0,ds1
ds0:
jdbc-url: jdbc:mysql://localhost:3306/user?userUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
username: root
password: root
ds1:
jdbc-url: jdbc:mysql://localhost:3306/user2019?userUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
username: root
password: root
minIdle: 10
##其它属性自己加
sharding:
## 设置默认数据源
default-data-source-name: ds0
## 默认分库规则
default-database-strategy:
standard:
precise-algorithm-class-name: com.murphy.shardingjdbc.sharding.PreciseAlgorithm
shardingColumn: user_id
tables:
user:
##设置每张表策略,可以覆盖默认策略五规则@see org.apache.shardingsphere.core.yaml.config.sharding.YamlShardingStrategyConfiguration
databaseStrategy:
complex:
shardingColumns: id
##复合分片
algorithmClassName: com.murphy.shardingjdbc.sharding.ComplexAlgorithm
## 这段是sharding的表达式,用来确认分片的范围从数据源0-1
actual-data-nodes: ds$->{0..1}.user
user_message:
actual-data-nodes: ds$->{0..1}.user_message
logging:
level:
com.murphy.shardingjdbc.mapper: debug
mybatis:
configuration:
map-underscore-to-camel-case: true
解释:
- names:你分了多少个库就写多少个别名用逗号分隔,注意要和下面的数据源配置保持一致
- ds0,ds1,dsn跟平时配置数据源一样
- 设置默认的数据源,默认分片规则,分片字段(比如我们用user_id)
- 表配置,每个表可单独设置分片规则(比如:我们上面默认按user_id分片,但在user表这个字段的字段名是id,这个时候我们可以为user表单独设置规则)(如配置中的user表)
- 如果表使用默认规则只需要配置库对应的表即可(如配置中的user_message表)
- 如果表无分片规则,如配置表这样的全局表:无需配置任何规则,只需要在默认数据库有表即可,其它库不需要(匹配不到规则走默认库)(如:config_info表)
4、编写分片规则算法
我们在配置里看到两个分片算法:接下来我们着重看系统内部提供的四种分片算法
com.murphy.shardingjdbc.sharding.PreciseAlgorithm
com.murphy.shardingjdbc.sharding.ComplexAlgorithm
二、五种分片策略讲解
就是我们配置文件里的default-database-strategy.standard和databaseStrategy.complex
我们这里配置的是databaseStrategy:数据源分片策略
当然还有表分片策略,跟数据源配置大同小异,我们这里以数据源为主:tableStrategy
分片策略:分片键+分片算法(分片键:将数据库水平拆分的关键字段;分片算法:把分片键的值按照一定的算法分配到不同的数据源)
主要类:org.apache.shardingsphere.core.yaml.config.sharding.YamlShardingStrategyConfiguration
public class YamlShardingStrategyConfiguration implements YamlConfiguration {
private YamlStandardShardingStrategyConfiguration standard;
private YamlComplexShardingStrategyConfiguration complex;
private YamlHintShardingStrategyConfiguration hint;
private YamlInlineShardingStrategyConfiguration inline;
private YamlNoneShardingStrategyConfiguration none;
}
1、standard(标准分片策略):处理类:org.apache.shardingsphere.core.strategy.route.standard.StandardShardingStrategy
提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。
StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。
PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。
RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理
2、complex(符合分片策略):处理类:org.apache.shardingsphere.core.strategy.route.complex.ComplexShardingStrategy
提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。
ComplexShardingStrategy支持多分片键,可根据业务自定义算法实现,提供ComplexKeysShardingAlgorithm分片算法
3、hint(hint表达式分片策略):处理类:org.apache.shardingsphere.core.strategy.route.hint.HintShardingStrategy
通过hint表达式,而非SQL解析做分片,对应算法:HintShardingAlgorithm
4、inline(行表达式分片策略):处理类:org.apache.shardingsphere.core.strategy.route.inline.InlineShardingStrategy
使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8}
表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0
到t_user_7
。
5、none(不分片策略)处理类:org.apache.shardingsphere.core.strategy.route.none.NoneShardingStrategy
查询所有的分片,谨慎使用(配置了分片表,单sql中没有分片键)
三、四种分片算法
分片策略里已经将策略提供的算法进行了对应,可看第三部分
主要在sharding-core-api包下的org.apache.shardingsphere.api.sharding.standard目录下
1、PreciseShardingAlgorithm(精确切分算法):
用于处理使用单一键作为分片键的=与IN进行分片的场景(项目中的user_id分片,项目中最常用的)
2、RangeShardingAlgorithm(范围切分算法):
用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景(这个用于无规律的范围,一般不用)
3、HintShardingAlgorithm(无分片键算法):
用于处理使用Hint行分片的场景
4、ComplexKeysShardingAlgorithm(复杂键切分算法):
用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度
面对复杂分片算法,一般都是初期没设计好,后期分片的时候要用多个字段用业务逻辑补,要根据不同的坑不同设计
四、问题
1、如果按用户id来分库,那么按手机号查询该怎么处理
- 可在数据库和分布式缓存同时维护一套用户id和手机号的映射关系,缓存可设置过期时间防止僵尸用户
- 在数据库主库维护一套映射关系,关系表可按手机号取模进行分表
2、如果用户id分片,id是自增的该怎么处理
- 可以按用户id区间递增分片,不用洗数据,如db1[1-1000W];db2[1000W-2000W],但存在访问热度问题
- 如果用户id用日期生成(雪花算法)可按日期分片,但存在数据分布不均、访问热度问题
涉及代码git地址:https://gitee.com/carpentor/spring-cloud-example
公众号主要记录各种源码、面试题、微服务技术栈,帮忙关注一波,非常感谢