1.sharding-jdbc分片策略(行分片策略踩坑笔记)
2.SpringBoot整合Sharding-JDBC分库分表--(一)分库分表介绍
3.shardingjdbcåtddlçåºå«
4.ShardingJdbc+Mybatis实现多数据源
5.shardingsphere源码阅读-兼容jdbc规范
sharding-jdbc分片策略(行分片策略踩坑笔记)
sharding-jdbc行分片策略默认不支持按分片键的源码范围查询
在开发时,对主键id做了范围查询。调试结果遇到如下报错:
Errorqueryingdatabase.Cause:java.lang.IllegalStateException:Inlinestrategycannotsupportrangesharding.原因:使用行分片策略原先的源码sharding-jdbc的分片策略配置是:
sharding:binding-tables:tableNametables:tableName:actual-data-nodes:ds0.tableName_$->{ 0..1}table-strategy:inline:sharding-column:idalgorithm-expression:tableName_$->{ id%2}上面的配置,使用了主键id作为单分片键,调试行表达式的源码分片策略。该分片策略只支持=和in操作符,调试聚合软件源码下载并不支持范围查询。源码如果你想要使用范围查询,调试你需要配置开启标准策略。源码
解决方案:使用标准分片策略对应配置:
sharding:binding-tables:tableNametables:tableName:table-strategy:standard:#用于单分片键的调试标准分片场景sharding-column:id#分片列名称precise-algorithm-class-name:com.project.com.PreciseModuloAlgorithm#精确分片算法类名称,用于=和IN。源码。调试该类需实现PreciseShardingAlgorithm接口并提供无参数的源码构造器range-algorithm-class-name:com.project.com.component.RangeModuloAlgorithm#范围分片算法类名称,用于BETWEEN,调试可选。源码该类需实现RangeShardingAlgorithm接口并提供无参数的构造器问题具体可参考,官方github上的issues提问:/manual/sharding-jdbc/configuration/config-yaml/
对于具体的分片算法类,可参考官方github上的example:/apache/shardingsphere-example
分片算法类需要自己根据实际场景进行开发,这里贴出官方example里的实现类:
publicfinalclassPreciseModuloAlgorithmimplementsPreciseShardingAlgorithm<Integer>{ @OverridepublicStringdoSharding(finalCollection<String>availableTargetNames,finalPreciseShardingValue<Integer>shardingValue){ for(Stringeach:availableTargetNames){ if(each.endsWith(shardingValue.getValue()%+"")){ returneach;}}thrownewUnsupportedOperationException();}}publicfinalclassRangeModuloAlgorithmimplementsRangeShardingAlgorithm<Integer>{ @OverridepublicCollection<String>doSharding(finalCollection<String>availableTargetNames,finalRangeShardingValue<Integer>shardingValue){ Collection<String>result=newLinkedHashSet<>(availableTargetNames.size());intminValue=shardingValue.getValueRange().hasLowerBound()?shardingValue.getValueRange().lowerEndpoint():Integer.MIN_VALUE;intmaxValue=shardingValue.getValueRange().hasUpperBound()?shardingValue.getValueRange().upperEndpoint():Integer.MAX_VALUE;//最大值减最小值,得到差longrange=BigInteger.valueOf(maxValue).subtract(BigInteger.valueOf(minValue)).longValue();//最小值得绝对值除的余数intbegin=Math.abs(minValue)%;//超过9直接返回可用的表名,这里的小妖启动指标源码9是,自己的分片策略值//假设我的分片策略是:对id除以,取余数if(range>9){ returnavailableTargetNames;}//如果差在分片策略内的,就直接取余数,得到对应的表名for(inti=begin;i<=range;i+=1){ for(Stringeach:availableTargetNames){ if(each.endsWith(i+"")){ result.add(each);}}}returnresult;}}sharding-jdbc分片策略分片策略包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键+分片算法,也就是分片策略。目前提供5种分片策略。
标准分片策略对应StandardShardingStrategy。提供对SQL语句中的=,>,<,>=,<=,IN和BETWEENAND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEENAND,>,<,>=,<=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEENAND将按照全库路由处理。
复合分片策略对应ComplexShardingStrategy。艾尚源码论坛复合分片策略。提供对SQL语句中的=,>,<,>=,<=,IN和BETWEENAND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
行表达式分片策略对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如:t_user_$->{ u_id%8}表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。
Hint分片策略对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的串口调试源码 c方式进行分片的策略。
不分片策略对应NoneShardingStrategy。不分片的策略。
SpringBoot整合Sharding-JDBC分库分表--(一)分库分表介绍
SpringBoot整合Sharding-JDBC分库分表--(一)分库分表详解
随着业务的迅速增长,数据库的负载压力剧增,性能瓶颈开始显现。这主要是因为关系型数据库的单机存储和处理能力有限,当数据量超过一定规模,即使优化索引和增加从库,性能也会显著下降。 应对策略主要有两个方案:一是提升硬件资源,如增加存储和CPU,但这成本高昂且效果有限;二是采用分库分表策略,将数据分散到多个数据库和表中,减轻单个数据库的负担。分库分表旨在通过数据的分解,使每个数据库和表的数据量减少,提升整体性能。 分库分表方式有四种:垂直分表和分库,以及水平分库和分表。垂直分表将表按字段拆分,安卓源码 投票常用字段和不常用字段分开,可以减少IO争抢,提高查询效率。垂直分库则按照业务逻辑将表分布在不同的数据库,进一步分散压力。水平分库是根据业务需求将数据分布在不同服务器,如商品库根据店铺ID拆分。水平分表则是在同一数据库内,将表拆分成多个,按商品ID进行划分。 然而,分库分表也带来了一些挑战,如事务一致性问题、跨节点查询复杂性、主键避重和公共表的处理。例如,数据分布式后可能导致事务处理的复杂性提升,以及跨库的查询和排序操作需要更复杂的逻辑。此外,需要设计全局唯一主键来解决跨库重复问题。 Sharding-JDBC,由当当网开发的开源分布式数据库中间件,简化了开发者在分库分表方面的操作。它是一个轻量级框架,兼容JDBC,提供数据分片和读写分离功能,使得应用程序能够透明地操作分布式数据库,无需关注底层的细节。通过Sharding-JDBC,可以简化应用对复杂分库分表策略的处理,提高开发效率。shardingjdbcåtddlçåºå«
shardingjdbcæ¯å½å½ç½çå é¨ååºå表ä¸é´ä»¶ï¼ç®åå·²ç»å¼æºï¼å¯ä»¥å¨githubä¸è¿è¡è·åï¼èTDDLåæ¯é¿éå é¨çååºå表ä¸é´ä»¶ï¼ç®åå°æªå¼æºï¼æ¬è´¨ä¸é½æ¯JDBCçä¸ç§åè£ ã详ç»è§ä¸å¾ShardingJdbc+Mybatis实现多数据源
实现Mybatis与多数据源结合的步骤如下:
首先,确保项目依赖正确,这与单数据源项目的依赖设置一致。
接着,配置Mybatis使用数据源的方式。这里采用注解方法,相关的类包括:注解类、枚举类、连接池配置信息类、用于存储数据源变量的ThreadLocal类,以及继承自AbstractRoutingDataSource的切面类和DruidConfig配置类。
在application配置文件中,定义数据源配置信息。
编写测试类,包含Mapper接口和对应的Mapper XML文件。在测试类中,执行不同方法,如list和listSharding。观察结果,list方法直接查询order_info表,而listSharding则从分表中获取数据,这验证了分表策略的正确实现。
整合Mybatis与多数据源的流程适用于实际场景,尤其在使用Mybatis的项目中常见。同时,Mybatisplus的整合也是常见的需求。后续文章将深入探索更多相关整合技术,希望能为读者提供帮助。
项目代码可以参考地址:gitee.com/shen-chuhao/w...
shardingsphere源码阅读-兼容jdbc规范
JDBC规范提供一套标准,让不同数据库厂商遵循统一接口操作数据库,从而简化应用程序开发。shardingsphere兼容此规范,通过重写接口实现兼容。
基于JDBC规范,shardingsphere采用适配器模式重写DataSource、Connection、Statement、ResultSet等关键接口,构建了一套完整的实现方案。适配器模式确保了shardingsphere能够以与JDBC规范一致的方式操作数据库,同时支持分库分表功能。
shardingsphere中,JdbcObject接口代表JDBC规范中的核心接口,包括DataSource、Connection、Statement等。通过包装器接口Wrapper以及其子类WrapperAdapter,shardingsphere实现了适配器模式,重写了这些接口的方法,同时保留了与JDBC规范的兼容性。
AbstractUnsupportedOperationJdbcObject和AbstractJdbcObjectAdapter作为抽象类,分别用于实现部分和全部接口方法。ShardingIdbcObject继承自AbstractJdbcObjectAdapter,包括ShardingDataSource、ShardingConnection、ShardingStatement等对象,这些对象都采用适配器模式重写JDBC规范接口,确保与JDBC规范无缝衔接。
以ShardingDataSource为例,其构造过程通过ShardingDataSourceFactory创建ShardingDataSource对象,将数据源、分库分表规则和属性等信息整合,同时初始化运行时上下文和静态代码块加载路由、SQL重写、结果集引擎等组件。ShardingDataSource内部的WrapperAdapter类维护方法调用信息,通过recordMethodInvocation和replayMethodsInvocation方法记录和回放方法调用。
AbstractDataSourceAdapter作为数据源适配器的抽象类,封装公共属性和方法,减少重复代码。此类中的dataSourceMap和databaseType属性分别保存数据源信息和数据库类型,getRuntimeContext方法用于获取分库分表的运行时上下文。
综上所述,shardingsphere通过适配器模式重写JDBC规范接口,实现了与JDBC规范的兼容性。不论使用sharding-jdbc还是原生JDBC,操作数据库的方式和流程保持一致,只是在实现细节上支持了分库分表功能,为开发者提供了一种灵活且高效的数据库管理方案。