分库分表中间件---ShardingJdbc
Posted ExcellentFramework
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分库分表中间件---ShardingJdbc相关的知识,希望对你有一定的参考价值。
伴随互联网的发展,与日俱增的海量数据已成为我们业务开展和软件开发的基础支撑,但这同时也加大了技术实现的难度和复杂度。合理采用分库分表技术应对海量数据和高并发对数据库的冲击,是不可避免的问题。今天我们为大家提供一种主流的分库分表中间件ShardingJdbc。
整体架构
系统架构的核心逻辑包含以下几点,我们一一开展详细解读:
分库分表规则配置
sql解析
sql改写
sql路由
sql多线程执行
结果归并
分库分表规则配置
支持JAVA编码实现配置
支持propertise配置
支持yml配置
支持基于Groovy的inline表达式
sql解析
SQL解析作为分库分表类产品的核心,性能和兼容性是最重要的衡量指标。Sharding-JDBC对JDBC核心接口进行封装重写,最大化实现JDBC协议,目前常见的SQL解析器主要有fdb/jsqlparser和Druid。Sharding-JDBC使用Druid作为SQL解析器,经实际测试,Druid解析速度是另外两个解析器的几十倍。
sql改写
sql改写分为两部分,一部分是将分表的逻辑表名称替换为真实表名称。另一部分是根据SQL解析结果替换一些在分片环境中不正确的功能。
sql路由
SQL路由是根据分片规则配置,将SQL定位至真正的数据源。主要分为单表路由、Binding表路由和笛卡尔积路由。
单表路由最为简单,但路由结果不一定落入唯一库(表),因为支持根据between和in这样的操作符进行分片,所以最终结果仍然可能落入多个库(表)。
Binding表可理解为分库分表规则完全一致的主从表。举例说明:订单表和订单详情表都根据订单ID作为分片键,任意时刻分片逻辑均相同。这样的关联查询和单表查询难度和性能相当。
笛卡尔积查询最为复杂,因为无法根据Binding关系定位分片规则的一致性,所以非Binding表的关联查询需要拆解为笛卡尔积组合执行。查询性能较低,而且数据库连接数较高,需谨慎使用。
sql执行
路由至真实数据源后,Sharding-JDBC将采用多线程并发执行SQL。
结果归并
结果归并包括4类:普通遍历类、排序类、聚合类和分组类。每种类型都会先根据分页结果跳过不需要的数据
普通遍历类最为简单,只需按顺序遍历ResultSet的集合即可。
排序类结果将结果先排序再输出,因为各分片结果均按照各自条件完成排序,所以采用归并排序算法整合最终结果。
聚合类分为3种类型,比较型、累加型和平均值型。比较型包括max和min,只返回最大(小)结果。累加型包括sum和count,需要将结果累加后返回。平均值则是通过SQL改写的sum和count计算,相关内容已在SQL改写涵盖,不再赘述。
分组类最为复杂,需要将所有的ResultSet结果放入内存,使用map-reduce算法分组,最后根据排序和聚合条件做相关处理。最消耗内存,最损失性能的部分即是此,可以考虑使用limit合理的限制分组数据大小
事务支持
不支持强一致性的分布式事务,支持最终一致性的柔性事务。
完全支持非跨库事务,例如:仅分表,或分库但是路由的结果在单库中。
完全支持因逻辑异常导致的跨库事务。例如:同一事务中,跨两个库更新。更新完毕后,抛出空指针,则两个库的内容都能回滚。
不支持因网络、硬件异常导致的跨库事务。例如:同一事务中,跨两个库更新,更新完毕后、未提交之前,第一个库死机,则只有第二个库数据提交。
sql支持
不支持包含冗余括号的SQL
不支持OR
不支持CASE THEN
子查询中,一旦在下层嵌套中再次找到包含数据表的子查询将直接抛出解析异常
INSERT:插入列必须含有分片键
以上是ShardingJdbc的整体架构和基本特性,后面我们还会继续为您介绍其他高级特性和项目实践。
以上是关于分库分表中间件---ShardingJdbc的主要内容,如果未能解决你的问题,请参考以下文章
ShardingSphere技术专题「ShardingJDBC实战阶段」SpringBoot之整合ShardingJDBC实现分库分表(JavaConfig方式)
ShardingJdbc-分表;分库分表;读写分离;一主多从+分表;一主多从+分库分表;公共表;数据脱敏;分布式事务
spring boot:用shardingjdbc实现多数据源的分库分表(shardingsphere 4.1.1/spring boot 2.3.1)