使用shardingsphere-jdbc实现分库功能

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 项目需要把150W+的用户基础数据进行分库存储,这对于一般的切换数据源的场景已不适用,故选择了shardingsphere-jdbc组件来完成

针对选择哪一个版本的shardingsphere刚开始有点纠结,不同版本的配置及支持范围有很大的不同,但最终统合考虑之后选择了5.0的版本,相对于目前来说这个版本支持的范围还是不错的,基本能满足当前业务的所有需求。


当前分库的整体需求是,将这150W的数据根据一定的规则存入不同的数据源中,每个数据源相对隔离:

1.png

但是按照shardingsphere的分库逻辑来说,不能采用传统的路由规则,例如根据组织id、人员id类进行分库,而需要根据业务采用自定义的路由hint模式。


具体hint的路由逻辑为:

public class PartyUserDbHintShardingAlgorithm implements HintShardingAlgorithm<String> {
    @SneakyThrows
    @Override
    public Collection<String> doSharding(Collection<String> collection, HintShardingValue<String> hintShardingValue) {
        log.info("*********进入分库策略*********");
        List<String> dataBaseList = new ArrayList<>();
        for (String value : hintShardingValue.getValues()) {
            if (collection.contains(value)) {
                dataBaseList.add(value);
            }
        }
        if (CollectionUtils.isEmpty(dataBaseList)) {
            log.error("查询分库结果失败,collection={},hintShardingValues={}", JSON.toJSONString(collection), JSON.toJSONString(hintShardingValue.getValues()));
            throw new Exception("执行操作失败,请联系管理员!");
        }
        log.info("分库结果:{}", dataBaseList);
        return dataBaseList;
    }
    @Override
    public void init() {
    }
    @Override
    public String getType() {
        return "hint-db-party-user";
    }
    @Override
    public Properties getProps() {
        return null;
    }
    @Override
    public void setProps(Properties props) {
    }
    // 这里getType为配置文件中的路由名称,具体可以参照下面的yml配置


使用shardingsphere组件嵌入到项目中,默认情况下shardingsphere会托管所有的数据源,即使是不需要分库分表的其他业务表的增删改查,也会被它所托管,理论情况下没什么问题,但是在集成的过程中发现,由于不参与分库分表的增删改查sql语句,很多采用了复杂的写法(例如多层的嵌套子查询,多聚合函数同时使用等),但shardingsphere在托管的情况下进行sql解析的时候会出现问题,所以去查询资料详细了解了一下,这个组件存在一定的sql不兼容情况,具体可查看链接:

http://www.gitweixin.com/?p=717

https://shardingsphere.apache.org/document/5.0.0-beta/cn/user-manual/shardingsphere-jdbc/unsupported-items/


这时候项目中又引进了另外一个组件dynamic,组中采用了dynamic+shardingsphere的方式来实现本次分库的需求,以下是具体的yml文件配置:

#基础数据源
  datasource:
    dynamic:
      datasource:
        master:
          type: com.alibaba.druid.pool.DruidDataSource
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://XXX:3306/XX?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
          username: XX
          password: XXX
          druid:
            publicKey: XXX
            # 初始化连接大小   默认:0
            initialSize: 10
            # 最小空闲连接数 默认:0
            minIdle: 10
            # 最大连接数 默认:8
            maxActive: 200
            .....
      primary: master
  #shardingsphere配置
  shardingsphere:
    datasource:
      common:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
      names: base,shangcheng,shangcheng-other
      base:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://XXX:3306/XX?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
        username: XX
        password: XXX
        filters: config
        connectionProperties: config.decrypt=true;config.decrypt.key=XXX
        # 初始化连接大小   默认:0
        initialSize: 10
        # 最小空闲连接数 默认:0
        minIdle: 10
        # 最大连接数 默认:8
        maxActive: 100
        .....
      shangcheng:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://XXX:3306/XX?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&tinyInt1isBit=false
        username: XX
        password: XXX
        filters: config
        connectionProperties: config.decrypt=true;config.decrypt.key=XXX
        # 初始化连接大小   默认:0
        initialSize: 10
        # 最小空闲连接数 默认:0
        minIdle: 10
        # 最大连接数 默认:8
        maxActive: 50
        .....
      shangcheng-other:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://XXX:3306/XX?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&tinyInt1isBit=false
        username: XX
        password: XXX
        filters: config
        connectionProperties: config.decrypt=true;config.decrypt.key=XXX
        # 初始化连接大小   默认:0
        initialSize: 10
        # 最小空闲连接数 默认:0
        minIdle: 10
        # 最大连接数 默认:8
        .....
    rules:
      sharding:
        tables:
          ob_party_user:
            actualDataNodes: shangcheng.ob_party_user,shangcheng-other.ob_party_user
            databaseStrategy:
              hint:
                shardingAlgorithmName: hint-db-party-user
            tableStrategy:
              hint:
                shardingAlgorithmName: hint-table-party-user
        sharding-algorithms:
          hint-db-party-user:
            type: hint-db-party-user
          hint-table-party-user:
            type: hint-table-party-user
        defaultTableStrategy:
          none:
        defaultDatabaseStrategy:
          none:
    props:
      sql-show: false


dynamic组件的目的是将整个项目的数据源托管方式分为2大部分,第一部分是默认的数据源托管模式,另一部分是shardingsphere托管模式(专门用于分库分表),这样的好处是不参与分库分表的操作走默认托管的数据源,参与分库分表的走shardingsphere托管的数据源,这样极大的减少了分库组件给项目带来的不兼容性。


业务的难点在于分库分表之后,如何能够快速定位指定数据源进行增删改查,因为用户表的访问是整个系统中最核心也是量最大的,所以根据业务的需求,根据组织id、人员id来查询用户信息是最常见的需求,故而将用户所属组织的关系进行redis缓存的存储。


使用用户与组织的缓存数据,项目采用在启动时将所有的用户组织关系存入到redis缓存中


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
Java
SpringBoot整合sharding-jdbc实现分库分表
SpringBoot整合sharding-jdbc实现分库分表
43 1
|
10月前
|
算法 Java 数据库连接
springboot整合sharding jdbc【分库】
springboot整合sharding jdbc【分库】
|
10月前
|
算法 Java 数据库连接
springboot整合sharding jdbc【分表】
springboot整合sharding jdbc【分表】
|
SQL 存储 算法
聊聊 Sharding-JDBC 分库分表
聊聊 Sharding-JDBC 分库分表
|
存储 SQL 缓存
分库分表之ShardingSphere(一)
分库分表之ShardingSphere
|
SQL cobar 算法
分库分表之ShardingSphere(二)
分库分表之ShardingSphere
|
SQL 算法 Java
ShardingSphere-Sharding-JDBC水平分库(1) | 学习笔记
快速学习ShardingSphere-Sharding-JDBC水平分库(1)。
147 0
ShardingSphere-Sharding-JDBC水平分库(1) | 学习笔记
|
存储 Java 中间件
ShardingSphere - Sharding - JDBC (公共表) | 学习笔记
快速学习ShardingSphere - Sharding - JDBC (公共表)。
72 0
ShardingSphere - Sharding - JDBC (公共表) | 学习笔记
|
监控 关系型数据库 MySQL
ShardingSphere-Sharding-JDBC (读写分离) | 学习笔记
快速学习ShardingSphere-Sharding-JDBC (读写分离)。
184 0
ShardingSphere-Sharding-JDBC (读写分离)  | 学习笔记
|
druid Java 关系型数据库
ShardingSphere-Sharding-JDBC 水平分表(搭建环境) | 学习笔记
快速学习ShardingSphere-Sharding-JDBC 水平分表(搭建环境)。
323 0
ShardingSphere-Sharding-JDBC 水平分表(搭建环境) | 学习笔记