每天多学一点点~
话不多说,这就开始吧…
最近有个业务需要分库分表,遂研究了下sharing。网上列出了一些取模的分库分表实现,但是按照时间分库分表,或者二者结合的很少,遂在这里记录一下。
shrdingsphere官网 各位有兴趣的去官网看看,中文的。。。
JDBC
定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。
proxy
类似于mycat。定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。 目前提供 MySQL 和 PostgreSQL 版本,它可以使用任何兼容 MySQL/PostgreSQL 协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat 等)操作数据,对 DBA 更加友好。
Sidecar
定位为 Kubernetes 的云原生数据库代理,以 Sidecar 的形式代理所有对数据库的访问。 通过无中心、零侵入的方案提供与数据库交互的的啮合层,即 Database Mesh,又可称数据库网格。好像还在规划中。
这里我选择了JDBC 方式。
<!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId&batis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.0</version></dependency><!-- sharding apache最新孵化的版本 --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.0.1</version></dependency>
CREATE TABLE `t_order` (`order_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单id(雪花算法)',`user_id` int(20) NOT NULL COMMENT '用户id',`address_id` bigint(20) NOT NULL COMMENT '地址id',`status` char(1) DEFAULT NULL COMMENT '订单状态',`create_time` datetime DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`order_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
#配置数据源 boke_1 boke_2
spring.shardingsphere.datasource.names=b0,b1# boke_0 数据源配置
spring.shardingsphere.pe=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.b0.driver-class-namesql.jdbc.Driver
spring.shardingsphere.datasource.b0.jdbc-url=jdbc:mysql://localhost:3306/boke_0?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.b0.username=root
spring.shardingsphere.datasource.b0.password=root# boke_1 数据源配置
spring.shardingsphere.pe=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.b1.driver-class-namesql.jdbc.Driver
spring.shardingsphere.datasource.b1.jdbc-url=jdbc:mysql://localhost:3306/boke_1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.b1.username=root
spring.shardingsphere.datasource.b1.password=root# 分库策略(水平) 以 user_id 取模 进行 分库
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=b$->{user_id % 2}# 绑定表 t_order 与 t_order_item
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item# t_order 分表策略
# 节点 b0.t_order_0,b1.t_order_1,b0.t_order_0,b1.t_order_1
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=b$->{0..1}.t_order_$->{0..1}
# 分表 id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
# 分表策略 order_id 取模
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id % 2}
# 使用SNOWFLAKE算法生成主键
spring.shardingsphere.sharding.tables.t_lumn=order_id
spring.shardingsphere.sharding.tables.t_pe=SNOWFLAKE
# 雪花算法的workId 机器为标识 0-1024
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=123# t_order_item 分表策略
# 节点 b0.t_order_item_0,b0.t_order_item_1,b1.t_order_item_0,b1.t_order_item_1
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=b$->{0..1}.t_order_item_$->{0..1}
# 分表策略 order_id 取模
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.sharding-column=order_id
# 分表策略 根据id取模,确定数据最终落在那个表中
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.algorithm-expression=t_order_item_$->{order_id % 2}
# 使用SNOWFLAKE算法生成主键
spring.shardingsphere.sharding.tables.t_order_lumn=order_item_id
spring.shardingsphere.sharding.tables.t_order_pe=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key-generator.props.worker.id=123# 广播表 address
spring.shardingsphere.sharding.broadcast-tables=t_address
这样配置好之后,其他就和springboot项目一样,直接用mybatis查询就可。
分片策略官网简介
包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。目前提供 5 种分片策略。
标准分片策略
对应 StandardShardingStrategy。提供对 SQ L语句中的 =, >, <, >=, <=, IN 和 BETWEEN AND 的分片操作支持。 StandardShardingStrategy 只支持单分片键,提供 PreciseShardingAlgorithm 和 RangeShardingAlgorithm 两个分片算法。 PreciseShardingAlgorithm 是必选的,用于处理 = 和 IN 的分片。 RangeShardingAlgorithm 是可选的,用于处理 BETWEEN AND, >, <, >=, <=分片,如果不配置 RangeShardingAlgorithm,SQL 中的 BETWEEN AND 将按照全库路由处理。
复合分片策略
对应 ComplexShardingStrategy。复合分片策略。提供对 SQL 语句中的 =, >, <, >=, <=, IN 和 BETWEEN AND 的分片操作支持。 ComplexShardingStrategy 支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
Hint分片策略
对应 HintShardingStrategy。通过 Hint 指定分片值而非从 SQL 中提取分片值的方式进行分片的策略。
不分片策略
对应 NoneShardingStrategy。不分片的策略。
规则
以订单为例,db 以 订单id 取模 分库, table 以 订单创建时间 分表
即 boke_0 boke_1 两个库,每个库中 t_order_2020_1 —t_order_2021_12 共24张表。
写两个类,实现 PreciseShardingAlgorithm 精确分片算法,一个用于db取模,一个用于table按月份分片。
DBShardingAlgorithm 用于 db 取模
/** @author :zjq* @date :2020/11/9 10:44* @description: TODO 数据表分表策略 TableShardingAlgorithm* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催*/
@Slf4j
public class DBShardingAlgorithm implements PreciseShardingAlgorithm<Long> {@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {System.out.println("DB PreciseShardingAlgorithm ");// 真实节点availableTargetNames.stream().forEach((item) -> {log.info("actual node db:{}", item);});log.info("logic table name:{},rout column:{}", LogicTableName(), ColumnName());//精确分片log.info("column value:{}", Value());long orderId = Value();long db_index = orderId & (2 - 1);for (String each : availableTargetNames) {if (each.equals("b"+db_index)) {return each;}}throw new IllegalArgumentException();}
}
TableShardingAlgorithm用于table按月份分片
/* * @author :zjq* @date :2020/11/9 10:44* @description: TODO 数据表分表策略 TableShardingAlgorithm* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催*/
@Slf4j
public class TableShardingAlgorithm implements PreciseShardingAlgorithm<Date> {@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) {System.out.println("table PreciseShardingAlgorithm ");// 真实节点availableTargetNames.stream().forEach((item) -> {log.info("actual node table:{}", item);});log.info("logic table name:{},rout column:{}", LogicTableName(), ColumnName());//精确分片log.info("column value:{}", Value());String tb_name = LogicTableName() + "_";// 根据当前日期 来 分库分表Date date = Value();String year = String.format("%tY", date);String mon =String.valueOf(Integer.parseInt(String.format("%tm", date))); // 去掉前缀0String dat = String.format("%td", date);// 选择表tb_name = tb_name + year + "_" + mon;System.out.println("tb_name:" + tb_name);for (String each : availableTargetNames) {System.out.println("t_order_:" + each);if (each.equals(tb_name)) {return each;}}throw new IllegalArgumentException();}
}
#配置数据源 boke_1 boke_2
spring.shardingsphere.datasource.names=b0,b1
spring.shardingsphere.sharding.default-data-source-name=b0# boke_0 数据源配置
spring.shardingsphere.pe=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.b0.driver-class-namesql.jdbc.Driver
spring.shardingsphere.datasource.b0.jdbc-url=jdbc:mysql://localhost:3306/boke_0?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&relaxAutoCommit=true&zeroDateTimeBehavior=convertToNull
spring.shardingsphere.datasource.b0.username=root
spring.shardingsphere.datasource.b0.password=root# boke_1 数据源配置
spring.shardingsphere.pe=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.b1.driver-class-namesql.jdbc.Driver
spring.shardingsphere.datasource.b1.jdbc-url=jdbc:mysql://localhost:3306/boke_1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&relaxAutoCommit=true&zeroDateTimeBehavior=convertToNull
spring.shardingsphere.datasource.b1.username=root
spring.shardingsphere.datasource.b1.password=rootspring.shardingsphere.sharding.tables.t_order.actual-data-nodes=b$->{0..1}.t_order_$->{2020..2021}_$->{1..12}
# 自定义 分片算法
# 分库分片健 database-strategy 数据库策略
spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.sharding-column=order_id
# 自定义 分片 策略
spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.precise-algorithm-class-name=der.sharding.time.DBShardingAlgorithm
# table-strategy 表 的 策略
spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.sharding-column=create_time
spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.precise-algorithm-class-name=der.sharding.time.TableShardingAlgorithm# 使用SNOWFLAKE算法生成主键
spring.shardingsphere.sharding.tables.t_lumn=order_id
spring.shardingsphere.sharding.tables.t_pe=SNOWFLAKE
# 雪花算法的workId 机器为标识 0-1024
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=123
这样就大功告成,经过测试,插入,分页查询,范围,精确查询,事务都是ok,但是因为选择了精确分片算法 ,分页和范围查询,会路由到2个db的24张表上,会有效率问题,所以要好好取舍,再研究研究~
世上无难事,只怕有心人,每天积累一点点,fighting!!!
本文发布于:2024-01-31 12:29:20,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170667535928518.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |