sharding sphere 4.0.0-RC1版本 按年分表(后续优化)

2024-05-02 10:18

本文主要是介绍sharding sphere 4.0.0-RC1版本 按年分表(后续优化),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. sharding sphere 4.0.0-RC1版本 按年分表(后续优化)

1.1. 概述

关于上一篇中LogShardingAlgorithmtables,我原先是在第一次调用的时候初始化,这样做虽然能实现功能,但每次调用都会走这个if判断,虽然性能损耗不大,但我觉得这不是业务应该走的逻辑顺序,我的理想是在LogShardingAlgorithm被实例化后去自动初始化tables

现在面对的问题是LogShardingAlgorithm的实例化是在Spring初始化中间执行的,且它本身的创建不是通过Spring的@Component等注解生成,而是通过反射实例化。若在实例化刚开始,也就是构造方法执行的时候执行初始化,那时候applicationContext还没有初始化完毕,拿不到环境参数,连Datasource也还没开始初始化

1.2. 解决方法

经过改造后,代码如下,单独拎出一个初始化方法,在类对象实例化后调用

/*** @author: laoliangliang* @description: 日志分片* @create: 2020/1/2 10:19**/
@Slf4j
public class LogShardingAlgorithm implements PreciseShardingAlgorithm, RangeShardingAlgorithm<Integer> {/*** 缓存存在的表*/private List<String> tables;private final String systemLogHead = "system_log_";public void init(){tables = DBUtil.getAllSystemLogTable();}@Overridepublic String doSharding(Collection availableTargetNames, PreciseShardingValue shardingValue) {String target = shardingValue.getValue().toString();String year = target.substring(target.lastIndexOf("_")   1, target.lastIndexOf("_")   5);if (!tables.contains(systemLogHead   year)) {DBUtil.createLogTable(year);tables.add(year);}return shardingValue.getLogicTableName()   "_"   year;}@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Integer> shardingValue) {Collection<String> availables = new ArrayList<>();Range valueRange = shardingValue.getValueRange();for (String target : tables) {Integer shardValue = Integer.parseInt(target.substring(target.lastIndexOf("_")   1, target.lastIndexOf("_")   5));if (valueRange.hasLowerBound()) {String lowerStr = valueRange.lowerEndpoint().toString();Integer start = Integer.parseInt(lowerStr.substring(0, 4));if (start - shardValue > 0) {continue;}}if (valueRange.hasUpperBound()) {String upperStr = valueRange.upperEndpoint().toString();Integer end = Integer.parseInt(upperStr.substring(0, 4));if (end - shardValue < 0) {continue;}}availables.add(target);}return availables;}
}

其中init方法通过另一个类实例化完成后调用,难点在于如何拿到该实例化的LogShardingAlgorithm

import cn.hutool.core.util.ReflectUtil;
import com.google.common.base.Optional;
import com.onegene.platform.system.log.LogShardingAlgorithm;
import org.apache.shardingsphere.core.rule.ShardingRule;
import org.apache.shardingsphere.core.rule.TableRule;
import org.apache.shardingsphere.core.strategy.route.ShardingStrategy;
import org.apache.shardingsphere.shardingjdbc.jdbc.core.ShardingContext;
import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.sql.DataSource;
/*** @author: laoliangliang* @description:* @create: 2020/1/18 8:29**/
@Component
public class StartupConfig {@Autowiredprivate DataSource dataSource;@PostConstructpublic void init() {this.loadLogInit();}private void loadLogInit() {if (dataSource instanceof ShardingDataSource) {ShardingDataSource sds = (ShardingDataSource) dataSource;ShardingContext shardingContext = sds.getShardingContext();ShardingRule shardingRule = shardingContext.getShardingRule();Optional<TableRule> systemLog = shardingRule.findTableRule("system_log");TableRule tableRule = systemLog.orNull();if (tableRule != null) {ShardingStrategy tableShardingStrategy = tableRule.getTableShardingStrategy();LogShardingAlgorithm preciseShardingAlgorithm = (LogShardingAlgorithm) ReflectUtil.getFieldValue(tableShardingStrategy, "preciseShardingAlgorithm");LogShardingAlgorithm rangeShardingAlgorithm = (LogShardingAlgorithm) ReflectUtil.getFieldValue(tableShardingStrategy, "rangeShardingAlgorithm");preciseShardingAlgorithm.init();rangeShardingAlgorithm.init();}}}
}

1.3. 总结

通过查看源码可以知道,它最后把LogShardingAlgorithm实例化的对象放入了ShardingDataSource,那我们就要从里面把它取出来,若它正常没提供get方法,那我们就用反射硬把它取出来

通过上述代码可以看出,范围分片和精确分片需要实例化两个类,我想是否可以合到一个类,网上也找了一下,发现有的版本使用ComplexKeysShardingAlgorithm算法是可以同时实现范围和精确分片查询的,但经过我实际测试,现在的4.0.0版本不行,原因在于以下代码,此为复杂分片源码

public final class ComplexShardingStrategy implements ShardingStrategy {@Getterprivate final Collection<String> shardingColumns;private final ComplexKeysShardingAlgorithm shardingAlgorithm;public ComplexShardingStrategy(final ComplexShardingStrategyConfiguration complexShardingStrategyConfig) {Preconditions.checkNotNull(complexShardingStrategyConfig.getShardingColumns(), "Sharding columns cannot be null.");Preconditions.checkNotNull(complexShardingStrategyConfig.getShardingAlgorithm(), "Sharding algorithm cannot be null.");shardingColumns = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);shardingColumns.addAll(Splitter.on(",").trimResults().splitToList(complexShardingStrategyConfig.getShardingColumns()));shardingAlgorithm = complexShardingStrategyConfig.getShardingAlgorithm();}@SuppressWarnings("unchecked")@Overridepublic Collection<String> doSharding(final Collection<String> availableTargetNames, final Collection<RouteValue> shardingValues) {Map<String, Collection<Comparable<?>>> columnShardingValues = new HashMap<>(shardingValues.size(), 1);String logicTableName = "";for (RouteValue each : shardingValues) {// 重点这里他把each的值强行转化成了ListRouteValue而范围查询对应的为BetweenRouteValue,所以在源码级别就被卡死了,除非重写策略,否则这个已经不能像以前那样用了columnShardingValues.put(each.getColumnName(), ((ListRouteValue) each).getValues());logicTableName = each.getTableName();}Collection<String> shardingResult = shardingAlgorithm.doSharding(availableTargetNames, new ComplexKeysShardingValue(logicTableName, columnShardingValues));Collection<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);result.addAll(shardingResult);return result;}
}

老梁讲Java

欢迎关注公众号,回复“教学视频”一起学习进步

这篇关于sharding sphere 4.0.0-RC1版本 按年分表(后续优化)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954023

相关文章

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

golang1.23版本之前 Timer Reset方法无法正确使用

《golang1.23版本之前TimerReset方法无法正确使用》在Go1.23之前,使用`time.Reset`函数时需要先调用`Stop`并明确从timer的channel中抽取出东西,以避... 目录golang1.23 之前 Reset ​到底有什么问题golang1.23 之前到底应该如何正确的

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq