Sharding-JDBC

一、概念:

        Sharding-JDBC是一个在客户端的分库分表工具。它是一个轻量级Java框架,在Java的JDBC层提供的额外服务。

        ShardingSphere提供标准化的数据分片、分布式事务和数据治理功能。

二、架构图:

  • ShardingRuleConfiguration 可以包含多个 TableRuleConfiguration(多张表),也可以设置默认的分库和分表策略。
  • 每个TableRuleConfiguration 可以针对表设置 ShardingStrategyConfiguration,包括分库分分表策略。
  • ShardingStrategyConfiguration 有 5 种实现(标准、行内、复合、Hint、无)
  • ShardingDataSourceFactory利用ShardingRuleConfiguration创建数据源。

三、基础概念:

逻辑表:

order_1、order_2、order_3

真实表:

order

数据节点:

数据分片的最小物理单元。由数据源名称和数据表组成,例: ds_0.order_0

绑定表:

指分片规则一致的主表和子表。例如: order和 t_order

广播表:

指所有的分片数据源中都存在的表,例如,字典表

分片策略:

包含分片键和分片算法;

  • 具体策略:
    • 标准分片策略(StandardShardingStrategy):用于处理 BETWEEN AND, >, =,
    • 复合分片策略(ComplexShardingStrategy):支持多分片键,提供对 SQL 语句中的 =, >, =,
    • 行表达式分片策略(InlineShardingStrategy): t_user_$->{u_id % 8} 表示 t_user 表根据 u_id 模 8,而分成 8 张表,表名称为 t_user_0 到 t_user_7
    • Hint分片策略(HintShardingStrategy):通过 Hint 指定分片值而非从 SQL 中提取分片值的方式进行分片的策略
    • 不分片策略(NoneShardingStrategy)
  • 分片键:用于分片的表字段
  • 分片算法:
    • 精确分片算法(单一分片键,例如 =、in)
    • 范围分片算法(单一分片键,例如 ETWEEN AND、>、=、
    • 复合分片算法(多片键)
    • Hint分片算法

主键生成策略:

通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。

四、执行流程:

SQL 解析 => 查询优化 => SQL路由 => SQL改写 => SQL执行 => 结果归并

五、使用方法:

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# pom.xml
<!--sharding-jdbc-->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# 自定义分片规则,需要Java SPI进行加载。
/**
 * 〈一句话功能简述〉<br>
 * 〈客户端用户表id自增生成〉
 *
 * @author hanxinghua
 * @create 2022/6/10
 * @since 1.0.0
 */
@Component
public class AppUserIdGenerator implements ShardingKeyGenerator {

    private RedisUtil redisUtil;

    @Override
    public Comparable<?> generateKey() {
        if (redisUtil == null) {
            synchronized (this) {
                if (redisUtil == null) {
                    redisUtil = SpringUtil.getBean("redisUtil");
                }
            }
        }
        return redisUtil.incr(AppUtil.APP_USER_ID, 1L);
    }

    @Override
    public String getType() {
        return "APPUSERID";
    }

    @Override
    public Properties getProperties() {
        return null;
    }

    @Override
    public void setProperties(Properties properties) {
    }
}
Java SPI 地址:
src/main/resources/META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator
ShardingKeyGenerator内容:
com.hippo.online.config.shardingjdbc.AppUserIdGenerator

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# 自定义分片规则
/**
 * 〈一句话功能简述〉<br>
 * 〈用户表分片规则〉
 *
 * @author hanxinghua
 * @create 2022/6/13
 * @since 1.0.0
 */
public class AppUserShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {

    @Override
    public String doSharding(Collection<String> targetTableNames, PreciseShardingValue<Integer> shardingValue) {
        String value = String.valueOf(shardingValue.getValue());
        for (String targetTableName : targetTableNames) {
            if (targetTableName.endsWith(value)) {
                return targetTableName;
            }
        }
        return "app_user_999";
    }
}
/**
 * 〈一句话功能简述〉<br>
 * 〈用户记录表分片规则〉
 *
 * @author hanxinghua
 * @create 2022/6/13
 * @since 1.0.0
 */
public class AppUserRecordShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {

    @Override
    public String doSharding(Collection<String> targetTableNames, PreciseShardingValue<Integer> shardingValue) {
        String value = String.valueOf(shardingValue.getValue());
        for (String targetTableName : targetTableNames) {
            if (targetTableName.endsWith(value)) {
                return targetTableName;
            }
        }
        return "app_user_record_999";
    }
}

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# yaml配置:
spring:
  shardingsphere:
    # 数据源配置
    datasource:
      names: ds0
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        ... ...    
    props:
      sql.show: true  # 打开sql输出日志
    sharding:
      defaultDataSourceName: ds0  # 默认数据源名称
      tables:
        # 逻辑表名称
        app_user:
          # 数据节点:数据源$->{0..N}.逻辑表名$->{0..N}
          actualDataNodes: ds0.app_user_$->{999..1011} # 现在是只分表不分库
          # 主键生成规则
          keyGenerator:
            column: id
            type: APPUSERID # 自定义
          # 拆分表策略
          tableStrategy:
            standard:
              shardingColumn: app_id
              preciseAlgorithmClassName: com.config.shardingjdbc.AppUserShardingAlgorithm
        # 逻辑表名称      
        app_user_record:
          actualDataNodes: ds0.app_user_record_$->{999..1011} # 现在是只分表不分库
          tableStrategy:
            standard:
              shardingColumn: app_id
              preciseAlgorithmClassName: com.config.shardingjdbc.AppUserRecordShardingAlgorithm
      # 绑定表
      bindingTables: app_user,app_user_record


# 表达式举例:
## ${begin..end}:表示范围区间
## ${[unit1, unit2, unit_x]}:表示枚举值
## db1.table_$->{[1,2]}
## t_user_$->{u_id % 8}:表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7

# 主键生成规则举例:
key-generator:
  column: id
  type: SNOWFLAKE  #雪花算法
  props:
    work.id: 0  # 表示雪花id机器标识位,取值范围[0,1024)
    max.vibration.offset: 2 # 在高并发下,每次生成id都可能跨毫秒,夸毫秒,则序列部分会从0开始计算,每次生成的id都是偶数,奇偶分片有问题

# 用于单分片键的标准分片举例:
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.sharding-column= #分片列名称
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.precise-algorithm-class-name= #精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.range-algorithm-class-name= #范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器

# 用于多分片键的复合分片举例:
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.sharding-columns= #分片列名称,多个列以逗号分隔
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.algorithm-class-name= #复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器

六、多数据源配置:

# pom.xml:
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.2.1</version>
</dependency>


# 配置多数据源:
## 设置严格模式,默认false(不启动)。启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源。
spring.datasource.dynamic.strict=true
## 设置默认的数据源或者数据源组,默认值即为master
spring.datasource.dynamic.primary=master
## 配置master数据源:
### 以下datasource相关,省略部分
spring.datasource.dynamic.datasource.master.type=
spring.datasource.dynamic.datasource.master.driverClassName =
 ... ...
## 配置shardingsphere相关数据源:
### 以下datasource相关,省略部分
spring.shardingsphere.datasource.names=ds-1
spring.shardingsphere.datasource.ds-1.type=
spring.shardingsphere.datasource.ds-1.driverClassName=
 ... ...
spring.shardingsphere.datasource.names=ds-2
spring.shardingsphere.datasource.ds-2.type=
spring.shardingsphere.datasource.ds-2.driverClassName=
 ... ...
 

# 数据源配置类:
/**
 * 〈一句话功能简述〉<br>
 * 〈配置数据源〉
 *
 * @author hanxinghua
 * @create 2022/6/16
 * @since 1.0.0
 */
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class, SpringBootConfiguration.class})
public class DataSourceConfig {

    /**
     * 分表数据源名称
     */
    public static final String SHARDING_DATA_SOURCE_NAME = "sharding";

    /**
     * 动态数据源配置项
     */
    @Autowired
    private DynamicDataSourceProperties dynamicDataSourceProperties;

    @Lazy
    @Resource
    private DataSource shardingDataSource;

    @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider() {
        Map<String, DataSourceProperty> datasourceMap = dynamicDataSourceProperties.getDatasource();
        return new AbstractDataSourceProvider() {
            @Override
            public Map<String, DataSource> loadDataSources() {
                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
                // 将Sharding-jdbc管理的数据源也交给动态数据源管理
                dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingDataSource);
                return dataSourceMap;
            }
        };
    }

    @Bean
    @Primary
    public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
        dataSource.setPrimary(dynamicDataSourceProperties.getPrimary());
        dataSource.setStrict(dynamicDataSourceProperties.getStrict());
        dataSource.setStrategy(dynamicDataSourceProperties.getStrategy());
        dataSource.setProvider(dynamicDataSourceProvider);
        dataSource.setP6spy(dynamicDataSourceProperties.getP6spy());
        dataSource.setSeata(dynamicDataSourceProperties.getSeata());
        return dataSource;
    }
}

 # 使用:
 访问没有分表的数据时使用默认的普通数据源,访问分表的数据时使用@DS("sharding")注解

七、数据迁移:

1.停机迁移(不推荐)

2.数据双写迁移

3.采用canal中间件迁移

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/779396.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WEB编程-了解Tomcat服务器

第⼀章⽹络编程 1.1 概述 计算机⽹络&#xff1a;是指将地理位置不同的具有独⽴功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在⽹络 操作系统、⽹络管理软件及⽹络通信协议的管理和协调下&#xff0c;实现资源共享和信息传递的计算机系统。 …

Python 获取tiktok视频评论回复数据 api接口

TIKTOK api接口 用于爬取tiktok视频评论回复数据 详细采集页面如图 https://www.tiktok.com/dailymail/video/7329872821990182190?qneural%20link&t1706783508149 请求API http://api.xxxx.com/tt/video/info/comment/reply?video_id7288909913185701125&comment_…

uni-app使用ucharts地图,自定义Tooltip鼠标悬浮显示内容并且根据@getIndex点击事件获取点击的地区下标和地区名

项目场景&#xff1a; uni-app使用ucharts地图,自定义Tooltip鼠标悬浮显示内容并且根据getIndex点击事件获取点击的地区下标和地区名 例如&#xff1a; 问题描述 官方给的文档有限&#xff0c;需要自己下载地图json数据然后自己渲染和编写鼠标悬浮显示内容以及获取点击地址…

Numpy矩阵运算

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Numpy概述 Numpy是Python的一个开源数值计算扩展库&#xff0c;主要用于存储和处理大型多维数组和矩阵&#xff0c;并且提供了大量的数学函数来操作这些数组。Numpy是Pytho…

为适配kubelet:v0.4 安装指定版本的docker

系统版本信息 cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) iso 文件下载地址 https://vault.centos.org/7.6.1810/isos/x86_64/CentOS-7-x86_64-DVD-1810.iso0.4 版本的kubelet 报错信息记录 E0603 19:00:38.273720 44142 kubelet.go:734] Error synci…

昇思25天学习打卡营第1天|初识MindSpore

# 打卡 day1 目录 # 打卡 day1 初识MindSpore 昇思 MindSpore 是什么&#xff1f; 昇思 MindSpore 优势|特点 昇思 MindSpore 不足 官方生态学习地址 初识MindSpore 昇思 MindSpore 是什么&#xff1f; 昇思MindSpore 是全场景深度学习架构&#xff0c;为开发者提供了全…

昇思25天学习打卡营第5天|网络与模型相关要素探讨

目录 从 MindSpore 模块中导入nn和ops 定义模型类 模型层 nn.Flatten nn.Dense nn.ReLU nn.SequentialCell nn.Softmax 模型参数 从 MindSpore 模块中导入nn和ops 将 MindSpore 整个模块引入到当前的 Python 脚本里&#xff0c;方便后续运用 MindSpore 所提供的各类功能…

【ue5】虚幻5同时开多个项目

正常开ue5项目我是直接在桌面点击快捷方式进入 只会打开一个项目 如果再想打开一个项目需要进入epic 再点击启动就可以再开一个项目了

预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来

预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来 目录 预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来 2.运行环境为Matlab2023b及以上&#xff1b; 3…

地级市数字经济指数、互联网用户数、数字金融普惠指数

2000-2022年地级市数字经济指数&#xff08;含控制变量&#xff09; 目录 数字经济如何改善环境污染 一、引言 二、文献综述 三、实证模型 四、数据来源 五、程序代码 六、运行结果 数字经济如何改善环境污染 摘要&#xff1a; 本论文旨在探讨数字经济对环境污染的改善作…

软考中级数据库系统工程师备考经验分享

前几天软考成绩出了&#xff0c;赶紧查询了一下发现自己顺利通过啦&#xff08;上午63&#xff0c;下午67&#xff0c;开心&#xff09;&#xff0c;因此本文记录一下我的备考经验分享给大家。因为工作中项目管理类的知识没有系统学习过&#xff0c;本来想直接报名软考高级证书…

Thisjavabean对象数组

This 1.概念 this是一个对象this是一个构造函数 2.介绍 解决局部变量和成员变量命名冲突 this在面向对象-封装那一篇里&#xff0c;有被两个地方提及。 但我们先简单给一个例子&#xff1a; public Person(String name, String phone, String qqPassword, String bankCar…

踩坑:Unity导出WebGL发布到手机上竖屏时强制显示横屏

具体的适配问题 公司的项目需要将游戏导出WebGL 发布到Web平台 本以为是个很简单的事情 谁知道却被个横竖屏适配搞的头晕 毕竟只有大学浅浅的学了下HTML这门语言 出来工作后基本上都是在跟C# Lua打交道 言归正传 看看具体问题吧 游戏如果从横屏进入 基本上不会有什么适配问题…

Rabnud博士加入了一个社交圈。起初他有5个朋友。他注意到他的朋友数量以下面的方式增长。第1周少了1个朋友......

Rabnud博士加入了一个社交圈。起初他有5个朋友。他注意到他的朋友数量以下面的 方式增长。第1周少了1个朋友&#xff0c;剩下的朋友数量翻倍&#xff1b;第2周少了2个朋友&#xff0c;剩下的朋友数量 翻倍。一般而言&#xff0c;第N周少了N个朋友&#xff0c;剩下的朋友数量翻倍…

HDF4文件转TIF格式

HDF4 HDF4&#xff08;Hierarchical Data Format version 4&#xff09;是一种用于存储和管理机器间数据的库和多功能文件格式。它是一种自描述的文件格式&#xff0c;用于存档和管理数据。 HDF4与HDF5是两种截然不同的技术&#xff0c;HDF5解决了HDF4的一些重要缺陷。因此&am…

Mean teacher are better role models-论文笔记

论文笔记 资料 1.代码地址 2.论文地址 https://arxiv.org/pdf/1703.01780 3.数据集地址 CIFAR-10 https://www.cs.utoronto.ca/~kriz/cifar.html 论文摘要的翻译 最近提出的Temporal Ensembling方法在几个半监督学习基准中取得了最先进的结果。它维护每个训练样本的标签…

设计模式探索:策略模式

1. 什么是策略模式&#xff08;Strategy Pattern&#xff09; 定义 策略模式&#xff08;Strategy Pattern&#xff09;的原始定义是&#xff1a;定义一系列算法&#xff0c;将每一个算法封装起来&#xff0c;并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而…

Unity 使用AVProMovieCapture实现Game视图屏幕录制

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 使用AVProMovieCapture实现Game视图屏幕录制 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心…

01背包问题-队列分支限界法-C++

0-1背包问题-队列分支限界法 问题描述&#xff1a; 给定n种物品和一个背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包中的物品&#xff0c;使得装入背包中物品的总价值最大&#xff1f;对于给定的n种物品的重量和价值&#xff0c;以及背包的容量&…

17-JS封装:工具类方法

目录 一、extend方法 二、添加一些工具类方法&#xff1a;$.xxx() 实现1&#xff1a; 实现2&#xff1a; 一、extend方法 jQuery.fn.extend jQuery.extend function(...args){let target,source[];source[...args];//判断2种情况 //$.extend({}) -->给$添加属性//$.…