当前位置: 首页 > article >正文

闲谭SpringBoot--ShardingSphere分库分表探究

文章目录

  • 1. 背景
  • 2. 创建数据库
  • 3. 修改yml配置文件
  • 4. 分片算法类
  • 5. 测试
  • 6 小结

1. 背景

接上文,我们对日志表,进行了按月的分表,这样每个月几百万条数据量还是扛得住的。

但是如果数据再多呢,除了提高硬件性能,还有一个可以考虑的方案就是分库。

例如,我们通过数据所属的地域、公司、部门等进行分库划分,当然具体根据什么划分,由需求决定。

本篇我们在上一篇《闲谭SpringBoot–ShardingSphere分表探究》的基础上,对日志表进一步按机构进行划分。

2. 创建数据库

首先创建两个数据库test、test1,每个数据库中都放入log_202411、log_202412、log202501、log_202502四张表,四张表结构是一样的如下:

注意,我们想实现按机构编号departId分库,然后同一个机构的数据,根据time再按月分表。

CREATE TABLE `log_202411` (
  `id` bigint(20) NOT NULL,
  `content` varchar(255) DEFAULT '',
  `time` datetime DEFAULT NULL,
  `departId` bigint(20) DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

3. 修改yml配置文件

配置两个数据库,注意ds0和ds1分别对应数据库test/test1。
在这里插入图片描述
配置分片方式,首先配置默认的库:
然后
然后针对log表配置分片规则,如下表达式意味着:对log表来说,数据库是ds加一个字符串,表则是log加一个字符串,至于加什么字符串,由分片算法指定。
在这里插入图片描述

接下来就是分片算法了,注意按机构分库我们只需要使用=和IN操作,所以只需要配置精确分片算法即可。

而时间还需要范围查询,所以按时间分表还需要一个范围分片算法。
在这里插入图片描述

完整配置如下:

server:
  port: 8080
  servlet:
    context-path: /sharding
spring:
  shardingsphere: # 数据库配置
    sharding:
      default-data-source-name: ds0 #注意:不分库时,默认的数据库源
      default-database-strategy: #默认的分库策略
        inline:
          sharding-column: id
          algorithm-expression: ds0
      tables: #数据分片规则配置
        log: # 逻辑表名称
          actual-data-nodes: ds${0..1}.log$->{1..2} # 由数据源名 + 表名组成(参考 Inline 语法规则)
          database-strategy: # 分库策略
            standard:
              precise-algorithm-class-name: org.example.sharding.config.DepartPreciseShardingAlgorithm # 精确分片算法类名称,用于=和IN
              sharding-column: departId # 分片列名称
          table-strategy: # 分表策略
            standard: # 行表达式分片策略
              precise-algorithm-class-name: org.example.sharding.config.MonthPreciseShardingAlgorithm # 精确分片算法类名称,用于=和IN
              sharding-column: time # 分片列名称
              range-algorithm-class-name: org.example.sharding.config.MonthRangeShardingAlgorithm  # 范围分片算法类名称,用于BETWEEN
          key-generator: # key生成器
            column: id
            type: SNOWFLAKE  # SnowflakeShardingKeyGenerator
            props:
              worker: # SNOWFLAKE算法的worker.id
                id: 100
              max: # SNOWFLAKE算法的max.tolerate.time.difference.milliseconds
                tolerate:
                  time:
                    difference:
                      milliseconds: 20
    datasource:
      names: ds0,ds1
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        name: test
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowMultiQueries=true
        username: root
        password: 123456
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        name: test1
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowMultiQueries=true
        username: root
        password: 123456

4. 分片算法类

编写按机构分库算法类:

/**
 * 按机构精确分片算法类
 */
/**
 * 按机构精确分片算法类
 */
@Slf4j
public class DepartPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
        // 获取分片键值
        Object object = shardingValue.getValue();
        Integer num = 0;//默认分片序号
        try {
            num = Integer.parseInt(object.toString()) % 2;//机构id为偶数,数据进入ds0;机构id为奇数,数据进入ds1;
        } catch (Exception e) {
            log.error("按机构精确分片算法类报错:{}", e.getMessage());
        }
        // 返回要进入的表名称
        String tableName = "ds" + num;
        log.info("精确分片结果:{}", tableName);
        return tableName;
    }
}

5. 测试

接下来发起测试,我们测试一个机构id为偶数的例子:
在这里插入图片描述

通过断点查看分片情况,首先触发了分库分片算法,数据进入ds0
在这里插入图片描述

然后触发了分表分片算法:
在这里插入图片描述
所以数据会进入ds0库的log_202501表。
在这里插入图片描述
然后我们测试下查询:
在这里插入图片描述
运行后分片结构如下:
在这里插入图片描述
说明我们的分片算法是正确的。

6 小结

通过分库分表,支持每月千万级数据量问题基本不大。

如果再多,每月上亿、十亿、百亿级别,哈哈,我也不知道啦,因为我还没遇到过。


http://www.kler.cn/a/473077.html

相关文章:

  • WebSocket监听接口
  • 《Spring Framework实战》9:4.1.4.依赖注入
  • Docker 容器自动化管理之脚本(Script for Docker Container Automation Management)
  • 25上软考中级【软件设计师】易混淆知识点
  • 【Nginx】设置https和http同时使用同一个端口访问
  • 英伟达 RTX 5090 显卡赋能医疗大模型:变革、挑战与展望
  • spring mvc源码学习笔记之一
  • Java高频面试之SE-10
  • 单片机-外部中断
  • springboot 集成 etcd
  • YCM上告警项怎么修改
  • 【转载记录】Scikit-learn 报错:’super’ object has no attribute ‘__sklearn_tags__’.
  • Perl语言的语法糖
  • 【HTML+CSS+JS+VUE】web前端教程-2-HTML5介绍和基础骨架
  • 【2024华为OD-E卷-100分-boss的收入】(题目+思路+JavaC++Python解析)
  • 【并发篇】CompletableFuture学习
  • JavaScript 正则表达式
  • 代码随想录算法训练营第1天(数组1)| 704. 二分查找、27. 移除元素、977.有序数组的平方
  • 【数据库】SQL相关知识点总结1(数据库约束、三大范式、关系模型、聚合函数)
  • 为什么页面无法正确显示?都有哪些HTML和CSS相关问题?
  • PHP语言的函数实现
  • svelte5中使用react组件
  • 跨界融合:人工智能与区块链如何重新定义数据安全?
  • MATLAB语言的软件工程
  • c#13新特性
  • 推动多语言语音科技迈向新高度:INTERSPEECH 2025 ML-SUPERB 2.0 挑战赛