Sharding-Jdbc 基础使用分享

核心概念

逻辑表

水平拆分的数据库(表)的相同逻辑和数据结构表的总称。例:订单数据根据主键尾数
拆分为10张表,分别是t_order_0到t_order_9,他们的逻辑表名为t_order。

真实表

在分片的数据库中真实存在的物理表。即上个示例中的t_order_0到t_order_9。

数据节点

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

绑定表

分片规则一致的主表和子表。例如:t_order表和t_order_item表,均按照order_id分
片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联
查询效率将大大提升。

广播表
指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。
适用于数据量不大且需要与海量数据的表进行关联查询的场景。字典表就是典型的场景。

Quick start

1. pom依赖引入

<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
  <version>${version}</version>
  <scope>compile</scope>
</dependency>

2. spring-boot使用

spring:
  shardingsphere:
    enabled: true
    datasource:
      #数据源名称  不配置的话不会创建数据源 
      #这里有个坑(使用下划线可能会有异常产生,字符不支持,如:m_0)
      names: m1,m2
      #数据源 m1配置
      m1:
        #数据库方言
        driver-class-name: com.mysql.cj.jdbc.Driver
        #数据库密码
        password: 1a!gHco@d2mrgf^*^4lwGpB^
        #数据源类型
        type: com.zaxxer.hikari.HikariDataSource
        #数据源地址
        jdbcUrl: jdbc:mysql://rm-wz9gtu4pe3f6vom022o.mysql.rds.aliyuncs.com:3306/ideamake_um?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
        #数据源用户名
        username: ideamake_dbuser
      #数据源 m1配置
      m2:
        driver-class-name: com.mysql.cj.jdbc.Driver
        password: 1a!gHco@d2mrgf^*^4lwGpB^
        type: com.zaxxer.hikari.HikariDataSource
        jdbcUrl: jdbc:mysql://rm-wz9gtu4pe3f6vom022o.mysql.rds.aliyuncs.com:3306/ideamake_um?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
        username: ideamake_dbuser
    #属性配置  是否打印sql
    props:
      sql:
        show: true
    #分片键配置
    sharding:
      tables:
        #分片键表名称
        um_agent_info:
          #数据源分片算法 只能有一个分片算法
          database-strategy:
            hint:
              #自定义分片算法类位置
              algorithmClassName: cn.ideamake.cloud.um.HintTestSharding
          #数据节点配置
          actual-data-nodes: m$->{1..2}.um_agent_info_$->{0..1}
          #表分片算法 只能有一个分片算法
          table-strategy:
            standard:
              #自定义分片算法类位置
              precise-algorithm-class-name: cn.ideamake.cloud.um.TestSharding
              #根据那个列来分片
              sharding-column: is_authentication

多库不配置数据源分配算法则每个库都会查询一次

属性配置项说明

名称数据类型说明默认值
sql-show (?)boolean是否在日志中打印 SQL打印 SQL 可以帮助开发者快速定位系统问题。日志内容包含:逻辑 SQL,真实 SQL 和 SQL 解析结果。如果开启配置,日志将使用 Topic ShardingSphere-SQL,日志级别是 INFOFALSE
sql-simple (?)boolean是否在日志中打印简单风格的 SQLFALSE
kernel-executor-size (?)int用于设置任务处理线程池的大小每个 ShardingSphereDataSource 使用一个独立的线程池,同一个 JVM 的不同数据源不共享线程池infinite
max-connections-size-per-query (?)int一次查询请求在每个数据库实例中所能使用的最大连接数1
check-table-metadata-enabled (?)boolean在程序启动和更新时,是否检查分片元数据的结构一致性FALSE
check-duplicate-table-enabled (?)boolean在程序启动和更新时,是否检查重复表FALSE
sql-federation-enabled (?)boolean是否开启联邦查询FALSE

常用的分片方式

inline表达式分片

    sharding:
      #默认分库策略
      default-database-strategy:
        inline:
          sharding-column: is_authentication
          #根据 Groovy 做的语句解析 m为库名
          algorithm-expression: m$->{is_authentication % 2 + 1}
      tables:
        um_agent_info:
          database-strategy:
            inline:
              sharding-column: is_authentication
              #根据 Groovy 做的语句解析
              algorithm-expression: m$->{is_authentication % 2 + 1}
          actual-data-nodes: m$->{1..2}.um_agent_info_$->{0..1}
          table-strategy:
            inline:
              #根据 Groovy 做的语句解析
              algorithm-expression: um_agent_info_$->{is_authentication % 2}
              sharding-column: is_authentication

standard方式分片

    sharding:
      tables:
        um_agent_info:
          database-strategy:
            inline:
              sharding-column: is_authentication
              algorithm-expression: m$->{is_authentication % 2 + 1}
#            hint:
#              algorithmClassName: cn.ideamake.cloud.um.HintTestSharding
          actual-data-nodes: m$->{1..2}.um_agent_info_$->{0..1}
          table-strategy:
            standard:
              #范围分片算法
              range-algorithm-class-name: cn.ideamake.cloud.um.TestRangeShardingAlgorithm
              #自定义分片算法类位置
              precise-algorithm-class-name: cn.ideamake.cloud.um.TestSharding
              #根据那个列来分片
              sharding-column: is_authentication

TestRangeShardingAlgorithm

范围分片

public class TestRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> shardingValue) {
        return null;
    }
}

image

TestSharding:

public class TestSharding implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        return availableTargetNames.stream()
                .filter(str -> str.endsWith(Convert.toStr(shardingValue.getValue() % 2))).findFirst().orElse("");
    }
}

image

hint方式分片

    sharding:
      tables:
        um_agent_info:
          database-strategy:
#            inline:
#              sharding-column: is_authentication
#              algorithm-expression: m$->{is_authentication % 2 + 1}
            hint:
              algorithmClassName: cn.ideamake.cloud.um.HintTestSharding
          actual-data-nodes: m$->{1..2}.um_agent_info_$->{0..1}
          table-strategy:
            standard:
              #自定义分片算法类位置
              precise-algorithm-class-name: cn.ideamake.cloud.um.TestSharding
              #根据那个列来分片
              sharding-column: is_authentication

配置HintManager

HintManager hintManager = HintManager.getInstance();
hintManager.addDatabaseShardingValue("um_agent_info","m1");
hintManager.addTableShardingValue("um_agent_info","m1");
IPage<AgentInfo> page = agentInfoService.page(new IdeamakePage<>(1, 10));
hintManager.close();

HintTestSharding

public class HintTestSharding implements HintShardingAlgorithm<Long> {

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, HintShardingValue<Long> shardingValue) {
        String appId = MDC.get("appId");
        List<String> list = Lists.newArrayList("wx34529b8c4ed59508", "wxbd819e2596295f99", "m1");
        if (list.contains(appId)) {
            return availableTargetNames.stream().filter(str -> str.contains(appId)).collect(Collectors.toList());
        }

        return availableTargetNames.stream().filter(str -> {
            for (String s : list) {
                if (str.contains(s)) {
                    return false;
                }
            }
            return true;
        }).collect(Collectors.toList());

    }
}

image

complex方式分片

    sharding:
      tables:
        um_agent_info:
          database-strategy:
#            inline:
#              sharding-column: is_authentication
#              algorithm-expression: m$->{is_authentication % 2 + 1}
            hint:
              algorithmClassName: cn.ideamake.cloud.um.HintTestSharding
          actual-data-nodes: m$->{1..2}.um_agent_info_$->{0..1}
          table-strategy:
            complex:
              #分片键 多个“,”隔开
              shardingColumns: is_authentication,open_id
              algorithmClassName: cn.ideamake.cloud.um.TestComplexKeysShardingAlgorithm

TestComplexKeysShardingAlgorithm

public class TestComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<Long> shardingValue) {

        System.out.println();
        return null;
    }
}

image

内置分片算法:
https://shardingsphere.apache.org/document/5.1.1/cn/user-manual/shardingsphere-jdbc/builtin-algorithm/sharding/

常见坑

LocalDateTime转换问题

image

可以跟源码看一下,Shareding-jdbc 并没有支持

image

直接抛出异常的。

默认的转换器 LocalDateTimeTypeHandler 调用的就是 getObject返回泛型的方法

image

两种方案解决

一: 自己修改源码,但是后面sharding-jdbc 升级了想要扩展就比较麻烦,代码需要迁移

二:继承BaseTypeHandler 重写里面方法

数据源名称带下划线

使用下划线可能会有异常产生,字符不支持,如:m_0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值