首页 > 其他分享 >sharding-jdbc配置

sharding-jdbc配置

时间:2023-08-05 16:55:14浏览次数:41  
标签:jdbc 策略 数据源 配置 order 算法 分片 sharding id

一、概念先行

1)SQL相关的

  • 逻辑表:水平拆分的数据库(表)的相同逻辑和数据结构表的总称。例:订单数据根据主键尾数拆分为2张表,分别是t_order_0到t_order_1,他们的逻辑表名为t_order。
  • 真实表:在分片的数据库中真实存在的物理表。例:示例中的t_order_0到t_order_1
  • 数据节点:数据分片的最小单元。由数据源名称和数据表组成,例:ds_0.t_order_0;ds_0.t_order_1;
  • 绑定表:指分片规则一致的主表和子表。例如:t_order表和t_order_item表,均按照order_id分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。
  • 广播表:指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表,示例中的t

2)分片相关

  • 分片键:用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片。
  • 分片算法:通过分片算法将数据分片,支持通过=、>=、<=、>、<、BETWEEN和IN分片。分片算法需要应用方开发者自行实现,可实现的灵活度非常高。
    目前提供4种分片算法:
  1. 精确分片算法:对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。
  2. 范围分片算法:对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景。需要配合StandardShardingStrategy使用。
  3. 复合分片算法:对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。
  4. Hint分片算法:对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。
  • 分片策略:包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。

    目前提供5种分片策略。

  1. 标准分片策略:对应StandardShardingStrategy。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。
  2. 复合分片策略:对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
  3. 行表达式分片策略:对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。
  4. Hint分片策略:对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略。
  5. 不分片策略:对应NoneShardingStrategy。不分片的策略。

3)配置相关

  • 分片规则:分片规则配置的总入口。包含数据源配置、表配置、绑定表配置以及读写分离配置等。
  • 数据源配置:真实数据源列表。
  • 表配置:逻辑表名称、数据节点与分表规则的配置
  • 数据节点配置:用于配置逻辑表与真实表的映射关系。
  • 分片策略配置:
    数据源分片策略:对应于DatabaseShardingStrategy。用于配置数据被分配的目标数据源。
    表分片策略:对应于TableShardingStrategy。用于配置数据被分配的目标表,该目标表存在与该数据的目标数据源内。故表分片策略是依赖与数据源分片策略的结果的。
  • 自增主键生成策略:通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。(雪花算法)

sharding-jdbc配置

sharding:
  jdbc:
    datasource:
      names: ds0 #指定数据源 名称可以自定义,注意:名称要跟后面的配置一致
      ds0: #配置数据源的连接信息
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.52.10:3306/ball?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true
        username: root
        password: Yifan123.
    config:
      sharding:
        props:
          sql.show: true #是否输出sql
        tables:
          sys_role: #逻辑表名
            key-generator-column-name: id #主键
            #分库分表数据节点
#            actual-data-nodes: ds$->{0..2}.t_order$->{0..1}               # 数据节点:多数据源$->{0..N}.逻辑表名$->{0..N}相同表
#            actual-data-nodes: ds0.t_order$->{0..1},ds1.t_order$->{2..4}  # 数据节点:多数据源$->{0..N}.逻辑表名$->{0..N}不同表
#            actual-data-nodes: ds0.t_order$->{0..4}                       # 指定单数据源的配置方式
#            actual-data-nodes: ds0.t_order0,ds1.t_order0,ds0.t_order1,ds1.t_order1 # 全部手动指定
            actual-data-nodes: ds0.sys_role${0..1}    #数据节点,均匀分布
            #数据源分片策略
#            database-strategy:
#              inline: #行表达式
#                sharding-column: id #按照指定列进行分库---分库策略使用ID字段取模
#                algorithm-expression: ds$->{user_id%2}  #按模运算分配
            #分表策略
            table-strategy:
              #标准分片算法
              standard:
                sharding-column: id
                # 精确分片算法,用于 = 和 IN。该类需实现 PreciseShardingAlgorithm 接口并提供无参数的构造器
                precise-algorithm-class-name: com.chain.utils.MyPreciseShardingAlgorithm
                # 范围分片算法类名称,用于 范围查询 可选。该类需实现 RangeShardingAlgorithm 接口并提供无参数的构造器
                range-algorithm-class-name: com.chain.utils.MyRangeShardingAlgorithm # inline: #行表达式 # sharding-column: id #按照指定列进行分表---分表策略使用ID字段取模 # algorithm-expression: sys_role${id % 2} #按模运算分配

ShardingJDBC提供了5种分片策略及分片算法

一、标准分片策略 StandardShardingStrategyConfiguration

支持单个分片键,提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持

1. 精确分片算法 MyPreciseShardingAlgorithm(必选)

/**
 * 精确匹配查询,需要实现PreciseShardingAlgorithm,可以实现对 `=`以及`in`的查询
 */
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    /**
     * 精确匹配查询
     *
     * @param tbNames       数据库中所有的事实表
     * @param shardingValue 分片相关信息
     * @return 返回匹配的数据源
     */
    @Override
    public String doSharding(Collection<String> tbNames, PreciseShardingValue<Long> shardingValue) {
        for (String tableName : tbNames) {
            /*
             * shardingValue.getValue() 为分片建的值,比如 id=2时,value就是 2
             * 比如:表分为user_1到user_6,id=1操作user_1表,id=6操作user_6表
             *
             * `+ 6`的目的是为了保证,id=6操作user_6表,运维6%6=0,需要再进行`+6`
             */
            long index = shardingValue.getValue() % tbNames.size();
            //String value = String.valueOf(index == 0 ? index + 6 : index);
            // 匹配满足当前分片规则的表名称
            if (tableName.endsWith(String.valueOf(index))) {
                return tableName;
            }
        }
        throw new RuntimeException("数据库不存在");
    }
}
View Code

2. 范围分片算法 MyRangeShardingAlgorithm(非必选,不配置则全库路由处理)

public class MyRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> tbNames, RangeShardingValue<Long> rangeShardingValue) {
        // 获取逻辑表名称
        String logicTableName = rangeShardingValue.getLogicTableName();

        // between and 的起始值,需要处理只有最大值或者只有最小值的情况
        boolean hasLowerBound = rangeShardingValue.getValueRange().hasLowerBound();
        boolean hasUpperBound = rangeShardingValue.getValueRange().hasUpperBound();

        // 只有最小值,比如:id > x
        if (hasLowerBound && !hasUpperBound) {
            // 直接返回所有表名称
            return tbNames;
        }

        // 只有最大值,比如:id < x
        if (!hasLowerBound && hasUpperBound) {
            long upper = rangeShardingValue.getValueRange().upperEndpoint();
            if (upper < tbNames.size()) {
                // 如果最大值小于表的总数,则返回需要的表名
                return matchMinAndMax(1, upper, logicTableName, tbNames);
            } else {
                // 如果最大值大于表的总数,则返回所有
                return tbNames;
            }
        }

        long lower = Long.valueOf(rangeShardingValue.getValueRange().lowerEndpoint());
        long upper = Long.valueOf(rangeShardingValue.getValueRange().upperEndpoint());

        // 拼接事实表名称
        return matchMinAndMax(lower, upper, logicTableName, tbNames);
    }

    private List<String> matchMinAndMax(long lower, long upper, String logicTableName, Collection<String> tbNames) {
        List<String> tableNameList = new ArrayList<>();
        for (long index = lower; index <= upper; index++) {
            long tableNum = index % tbNames.size();
            // 事实表后缀
            //String suffix = String.valueOf(tableNum == 0 ? tableNum + 6 : tableNum);
            String tableName = logicTableName + tableNum;
            if (tbNames.contains(tableName)) {
                // 添加满足要求的表名称
                tableNameList.add(tableName);
            }

            // 如果满足要求的表已经覆盖了所有表,此处处理是为了方式查询区间过大,而分表不多,导致的过度遍历
            if (tableNameList.size() == tbNames.size()) {
                return tableNameList;
            }
        }
        return tableNameList;
    }
}
View Code

二、复合分片策略 ComplexShardingStrategyConfiguration

支持多个分片键,提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。

 

三、Inline表达式分片策略 InlineShardingStrategyConfiguration

使用Groovy的Inline表达式,提供对SQL语句中的=和IN的分片操作支持

四、Hint分片策略 HintShardingStrategyConfiguration

通过Hint而非SQL解析的方式分片的策略

五、不分片的策略 NoneShardingStrategyConfiguration

 

标签:jdbc,策略,数据源,配置,order,算法,分片,sharding,id
From: https://www.cnblogs.com/yifanSJ/p/17608197.html

相关文章

  • 计算机的基本原理与配置
    1.数据链路层是什么数据链路层负责网络中相邻节点之间可靠的数据通信,并进行有效的流量控制。在局域网中,数据链路层使用帧完成主机对等层之间数据的可靠传输。2.数据链路层的功能数据链路的建立、维护与拆除帧包装、帧传输、帧同步帧的差错恢复流量控制3.以太网工作在数据链路层4.以......
  • REHL配置Vsftpd
    FTP简介FTP(FileTransferProtocol)是一种用于在计算机之间传输文件的标准网络协议。在FTP中,有两种传输模式:主动模式(ActiveMode)和被动模式(PassiveMode)。主动模式:在主动模式下,客户端首先建立与服务器的命令连接(使用端口21),然后发送PORT命令指定客户端数据端口(通常是一个随机选择......
  • 谨科E-522 配置拉满的NAS主机 (N5105、四个8125B、双M2、5盘位)
    先看下这个大家伙的外观  优秀的背板,支持顺序上电,顺序启动 后面 主板 这个主板和我们的畅网也比较像重点来了,给他安装一个群晖系统试试  没问题可以安装  等待中 ......
  • 安装 配置 正向 解析 DNS方法
    安装配置正向解析DNS方法1,安装dhcp[root@localhost~]#yuminstallbind*-y2,关闭防火墙和selinux[root@localhost~]#systemctlstopfirewalld.service关闭防火墙[root@localhost~]#setenforce0关闭selinux3,查看bind文件列表[root@localhost~]#rpm-qlbind......
  • 动态配置与服务屏蔽
    服务提供者:user-service-provider 服务消费者:order-service-consumer 场景一:屏蔽消费者  1.屏蔽后会默认添加一条动态配置2.发起请求后,提供者的服务默认会返回null ......
  • OpenGL入门——配置环境
    OpenGL有意将建一个上下文(Context)和一个用于显示的窗口的操作抽象出去,所以我们就得自己处理创建窗口,定义OpenGL上下文以及处理用户输入。有一些特别针对OpenGL创建窗口和上下文用来渲染的库,比如GLUT,SDL,SFML和GLFW。这里先选择使用跟主页-LearnOpenGLCN(learnopengl-cn.git......
  • keil5中文乱码配置
    UTF-8好像没用了?这边用如图所示CHines的简体字。......
  • C#数据库连接配置文件存放至App.Config
    目录使用VisualStudio使用Rider 安装Nuget包获取配置连接数据库使用VisualStudio在需要添加配置文件的类右键-添加-新建项 选择应用配置文件,注意名称有格式要求 使用vs生成的话初始化代码是有的,然后输入的时候是有提示的使用Rider右键需要添加配置文件的项目,Add-File 使用Ri......
  • 【Spring Boot 丨类型安全配置属性 】
    本篇来讲一讲外部化配置类型安全属性(类型安全配置属性)类型安全配置属性  使用@Value("${property}")注释来注入配置属性有时可能很麻烦,尤其是处理多个属性或您的数据本质上是层次结构的情况下。SpringBoot提供了另一种使用属性的方法,让强类型bean管理和验证应用程......
  • vscode配置gitbash终端
    VSCode是一款微软出的轻量级编辑器,它本身只是一款文本编辑器而已,所有的功能都是以插件扩展的形式所存在,想用什么功能就安装对应的扩展即可,非常方便,同时也支持非常多的主题和图标,外观比较好看,重要的是VSCode支持各大主流操作系统,包括Windows、Linux和MacOS。所以就选择它作为自己的......