sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地

Sharding-JDBC(现为Apache ShardingSphere的一部分)允许你自定义分片策略。以下是一个使用Spring框架实现的demo,该demo展示了如何以公司ID作为分片键,并将公司ID对应的表后缀存入Redis中,以实现数据的分片存储。

步骤1:添加依赖

首先,在你的pom.xml文件中添加必要的依赖项,包括Spring Boot、Sharding-JDBC和Redis相关的依赖。

java 复制代码
【xml】
 <dependencies>
    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    <!-- Sharding-JDBC Spring Boot Starter -->
    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
        <version>你的版本号</version>
    </dependency>
    
    <!-- Redis Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    <!-- 其他依赖项 -->
</dependencies>

步骤2:配置Redis

在application.yml或application.properties文件中配置Redis连接信息。

java 复制代码
【yaml】
 spring:
  redis:
    host: localhost
    port: 6379

步骤3:定义自定义分片策略

创建一个类实现ShardingAlgorithm<String, String>接口(或适用于你使用的Sharding-JDBC版本的相应接口)。这个类将负责根据公司ID计算表后缀。

java 复制代码
【java】
 import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.LinkedHashSet;

@Component
public class CustomTableShardingAlgorithm implements PreciseShardingAlgorithm<String> {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        String companyId = shardingValue.getValue();
        String tableSuffix = redisTemplate.opsForValue().get("companyIdToTableSuffix:" + companyId);
        
        // 如果Redis中没有缓存,则计算并存储表后缀(这里简单使用哈希取模作为示例)
        if (tableSuffix == null) {
            int hash = companyId.hashCode();
            int tableIndex = Math.abs(hash % availableTargetNames.size());
            tableSuffix = availableTargetNames.toArray(new String[0])[tableIndex];
            
            // 存储到Redis中(可以选择设置过期时间)
            redisTemplate.opsForValue().set("companyIdToTableSuffix:" + companyId, tableSuffix);
        }
        
        // 这里返回的是表的实际名称或后缀,根据实际情况调整
        // 假设表名格式为:product_${tableSuffix}
        return "product_" + tableSuffix.split("_")[1]; // 根据实际情况调整
    }

    // 注意:这个方法可能需要根据实际情况调整,因为availableTargetNames可能包含的是逻辑表名的一部分或全部
    // 这里假设它包含的是完整的表名后缀(如product_0, product_1等),并且我们从后缀中提取实际的索引部分
}

注意:上面的doSharding方法实现有一个问题,即它假设availableTargetNames包含的是完整的表名后缀,并且从后缀中提取索引。这通常不是Sharding-JDBC的标准用法。在实际应用中,你可能需要调整这个逻辑,以便正确地从逻辑表名集合中选择一个表名。此外,上面的代码片段在处理Redis缓存时也有简化,你可能需要添加更多的错误处理和缓存更新逻辑。

步骤4:配置Sharding-JDBC

在application.yml或application.properties文件中配置Sharding-JDBC,指定数据源、表规则和你自定义的分片策略。

【yaml】

java 复制代码
 spring:
  shardingsphere:
    datasource:
      # 配置数据源信息
      names: ds0
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/your_database
        username: your_username
        password: your_password
    sharding:
      tables:
        product:
          actual-data-nodes: ds0.product_$->{0..9} # 假设你有10个分片表
          table-strategy:
            standard:
              sharding-column: company_id # 分片键
              sharding-algorithm-name: customTableShardingAlgorithm # 自定义分片策略名称
      sharding-algorithms:
        customTableShardingAlgorithm:
          type: CLASS_BASED
          props:
            strategy: your.package.name.CustomTableShardingAlgorithm # 自定义分片策略类的全限定名

注意:上面的配置有几个问题需要注意:

  1. actual-data-nodes的配置应该与你的实际数据库表结构相匹配。

  2. sharding-column应该与你的数据库表中的实际列名相匹配。

  3. sharding-algorithm-name和type: CLASS_BASED以及props.strategy应该正确指向你的自定义分片策略类。

然而,由于Sharding-JDBC的配置方式可能会随着版本的更新而发生变化,因此上述配置可能需要根据你使用的具体版本进行调整。

步骤5:编写服务层和控制器层代码

最后,编写服务层和控制器层代码,以便你可以通过Spring Boot应用程序与分片后的数据库进行交互。

由于这个demo的目的是展示如何自定义分片策略,因此具体的服务层和控制器层代码将取决于你的业务需求。你可以根据需要编写相应的代码来插入、查询和更新数据。

总结

这个demo提供了一个基本的框架,展示了如何在Spring框架中使用Sharding-JDBC自定义分片策略,并将分片信息存储在Redis中。然而,由于Sharding-JDBC和Spring的配置可能会随着版本的更新而发生变化,因此在实际应用中,你需要根据你使用的具体版本进行相应的调整和优化。此外,还需要注意处理Redis缓存的一致性、可用性和性能等问题。

相关推荐
callJJ44 分钟前
Spring Data Redis 两种编程模型详解:同步 vs 响应式
java·spring boot·redis·python·spring
KmSH8umpK2 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第七篇
数据库·redis·分布式
0xDevNull3 小时前
Linux 中 Nginx 代理 Redis 的详细教程
redis·后端
倒霉蛋小马3 小时前
【Redis】什么是缓存穿透?
缓存
MiNG MENS4 小时前
nginx 代理 redis
运维·redis·nginx
DevilSeagull5 小时前
MySQL(2) 客户端工具和建库
开发语言·数据库·后端·mysql·服务
远洪6 小时前
claude code 国内安装使用
数据库·mysql
千月落7 小时前
Redis数据迁移
数据库·redis·缓存
小编码上说8 小时前
LSH(局部敏感哈希)分桶,海量数据下的相似性搜索解决方案
java·spring boot·缓存·langchain4j·lsh·局部敏感哈希·ai调用优化
wangbing11258 小时前
MySQL 官方 GPG 密钥过期问题
数据库·mysql