sharding-jdbc分片功能学习笔记

news2024/12/24 20:53:27

sharding-jdbc是sharding-sphere下的一个模块,可以理解为增强版的jdbc,用于解决分库分表、读写分离问题,本文基于4.1.1版本进行说明数据分片功能的流程

该版本提供了如下功能

1.数据分片(包括强制路由功能)

2.读写分离

3.编排治理(接入配置中心和配置动态刷新)

4.分布式事务

5.数据脱敏

本文着重于数据分片功能的解析

1.相关概念

  • 表相关概念
名词概念
逻辑表水平拆分后有相同逻辑和数据结构的表的总称,如:t_oder_0~9,逻辑表为t_oder
真实表在数据库真实存在的表
数据节点数据分片的最小单元,由数据源+表组成 如ds_0.t_order_0
绑定表指分片规则一致的两个表,如订单和订单明细通过用户或订单id进行分片,绑定后会减少路由sql数量
广播表分片数据源中都存在的表,适用于数据量不大且需要与海量数据关联查询的场景,如元数据、字典表等
  • 分片相关概念
名词概念
分片键用于水平拆分的字段,支持多个
分片算法具体的数据路由策略,目前提供4种分片算法
  • 精确分片
用于处理单一分片键的场景,支持=&IN,实现策略PreciseShardingAlgorithm
  • 范围分片
用于处理单一分片键的场景,支持between and、>、<、>=、<=场景,实现策略RangeShardingAlgorithm
  • 复合分片算法
用于处理多分片键的场景,需要开发者自行处理路由逻辑,实现策略ComplexKeysShardingAlgorithm
  • Hint分片算法
可用于sharding-jdbc不支持的sql场景,如 insert into xx select * from xx where ...,配合HintManager(本地线程)使用
分片策略分片算法封装,可表示数据源、数据表的分片策略,配置时关注
  • 标准分片策略
StandardShardingStrategy 单一分片键场景使用
  • 复合分片策略
ComplexShardingStrategy 复合分片策略,多分片键场景使用
  • 行内表达式分片策略
InlineShardingStrategy 提供groovy表达式的单一分片键处理,减少冗余的代码开发
  • Hint分片策略
HintShardingStrategy 不通过解析sql传入分片信息,直接从本地线程取
  • 不分片策略
NoneShardingStrategy 返回所有可选的节点
层级关系为 分片引擎->分片策略->分片算法

2.接入方式

1.原生接入

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>${sharding-sphere.version}</version>
</dependency>

引入依赖后,可以使用yaml配置解析为bean的模式,也可以直接使用bean模式进行配置

  • yaml配置,摘自官方示例

    dataSources: #数据源配置,支持多个数据源
      ds_0: !!com.zaxxer.hikari.HikariDataSource #<!!数据库连接池实现类>
        driverClassName: com.mysql.jdbc.Driver #数据库驱动名
        jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 #数据库url链接
        username: root #数据库用户名
        password: #数据库密码
      ds_1: !!com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.jdbc.Driver
        jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        username: root
        password:
    
    shardingRule:
      tables: #数据分片规则,可配置多个逻辑表
        t_order: #逻辑表名称
          actualDataNodes: ds_${0..1}.t_order_${0..1} # 数据节点,由数据源名+表名组成,小数点分割,支持inline表达式。缺省表示使用已知数据源与逻辑表名称生成数据节点,用于广播表或分库表
          tableStrategy: #分表逻辑,同分库策略
            standard: #单分片键
              shardingColumn: order_id #分片列名
              preciseAlgorithmClassName: org.apache.shardingsphere.example.algorithm.PreciseModuloShardingTableAlgorithm #精确分片算法 =&IN
              rangeAlgorithmClassName: org.apache.shardingsphere.example.algorithm.RangeModuloShardingTableAlgorithm # 范围分片 between
          keyGenerator:
            type: SNOWFLAKE #自增列生成类型,可自定义id生成
            column: order_id # 自增列名称
            props:
              worker.id: 123        
        t_order_item:
          actualDataNodes: ds_${0..1}.t_order_item_${0..1}
          tableStrategy:
            standard:
              shardingColumn: order_id
              preciseAlgorithmClassName: org.apache.shardingsphere.example.algorithm.PreciseModuloShardingTableAlgorithm
              rangeAlgorithmClassName: org.apache.shardingsphere.example.algorithm.RangeModuloShardingTableAlgorithm
          keyGenerator:
            type: SNOWFLAKE
            column: order_item_id
            props:
              worker.id: 123        
      bindingTables:
        - t_order,t_order_item #绑定表规则表,需要保证绑定表间的插入逻辑、数据节点一致,好处是联表查询时不会出现笛卡尔积的情况
      broadcastTables: #广播表
        - t_address
      defaultDatabaseStrategy: #默认数据库分片策略,同分库策略
        standard:
          shardingColumn: user_id
          preciseAlgorithmClassName: org.apache.shardingsphere.example.algorithm.PreciseModuloShardingDatabaseAlgorithm
          rangeAlgorithmClassName: org.apache.shardingsphere.example.algorithm.RangeModuloShardingDatabaseAlgorithm

    props: #属性配置
      sql.show: #是否开启SQL显示,默认值: false
      executor.size: #工作线程数量,默认值: CPU核数
      max.connections.size.per.query: # 每个查询可以打开的最大连接数量,默认为1,
      check.table.metadata.enabled: #是否在启动时检查分表元数据一致性,默认值: false

    max.connections.size.per.query配置实际使用时需要关注,相关文章

2.spring接入

依赖引入

<!-- for spring boot -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>${sharding-sphere.version}</version>
</dependency>

<!-- for spring namespace -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-namespace</artifactId>
    <version>${sharding-sphere.version}</version>
</dependency>

配置示例

spring.shardingsphere.datasource.names= #数据源名称,多数据源以逗号分隔

spring.shardingsphere.datasource.<data-source-name>.type= #数据库连接池类名称
spring.shardingsphere.datasource.<data-source-name>.driver-class-name= #数据库驱动类名
spring.shardingsphere.datasource.<data-source-name>.url= #数据库url连接
spring.shardingsphere.datasource.<data-source-name>.username= #数据库用户名
spring.shardingsphere.datasource.<data-source-name>.password= #数据库密码
spring.shardingsphere.datasource.<data-source-name>.xxx= #数据库连接池的其它属性

spring.shardingsphere.sharding.tables.<logic-table-name>.actual-data-nodes= #由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持inline表达式。缺省表示使用已知数据源与逻辑表名称生成数据节点,用于广播表(即每个库中都需要一个同样的表用于关联查询,多为字典表)或只分库不分表且所有库的表结构完全一致的情况

#分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一

#用于单分片键的标准分片场景
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.sharding-column= #分片列名称
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.precise-algorithm-class-name= #精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.range-algorithm-class-name= #范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器

#用于多分片键的复合分片场景
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.sharding-columns= #分片列名称,多个列以逗号分隔
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.algorithm-class-name= #复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器

#行表达式分片策略
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.inline.sharding-column= #分片列名称
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.inline.algorithm-expression= #分片算法行表达式,需符合groovy语法

#Hint分片策略
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.hint.algorithm-class-name= #Hint分片算法类名称。该类需实现HintShardingAlgorithm接口并提供无参数的构造器

#分表策略,同分库策略
spring.shardingsphere.sharding.tables.<logic-table-name>.table-strategy.xxx= #省略

spring.shardingsphere.sharding.tables.<logic-table-name>.key-generator.column= #自增列名称,缺省表示不使用自增主键生成器
spring.shardingsphere.sharding.tables.<logic-table-name>.key-generator.type= #自增列值生成器类型,缺省表示使用默认自增列值生成器。可使用用户自定义的列值生成器或选择内置类型:SNOWFLAKE/UUID
spring.shardingsphere.sharding.tables.<logic-table-name>.key-generator.props.<property-name>= #属性配置, 注意:使用SNOWFLAKE算法,需要配置worker.id与max.tolerate.time.difference.milliseconds属性。若使用此算法生成值作分片值,建议配置max.vibration.offset属性

spring.shardingsphere.sharding.binding-tables[0]= #绑定表规则列表
spring.shardingsphere.sharding.binding-tables[1]= #绑定表规则列表
spring.shardingsphere.sharding.binding-tables[x]= #绑定表规则列表

spring.shardingsphere.sharding.broadcast-tables[0]= #广播表规则列表
spring.shardingsphere.sharding.broadcast-tables[1]= #广播表规则列表
spring.shardingsphere.sharding.broadcast-tables[x]= #广播表规则列表

spring.shardingsphere.sharding.default-data-source-name= #未配置分片规则的表将通过默认数据源定位
spring.shardingsphere.sharding.default-database-strategy.xxx= #默认数据库分片策略,同分库策略
spring.shardingsphere.sharding.default-table-strategy.xxx= #默认表分片策略,同分表策略
spring.shardingsphere.sharding.default-key-generator.type= #默认自增列值生成器类型,缺省将使用org.apache.shardingsphere.core.keygen.generator.impl.SnowflakeKeyGenerator。可使用用户自定义的列值生成器或选择内置类型:SNOWFLAKE/UUID
spring.shardingsphere.sharding.default-key-generator.props.<property-name>= #自增列值生成器属性配置, 比如SNOWFLAKE算法的worker.id与max.tolerate.time.difference.milliseconds

spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.master-data-source-name= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.slave-data-source-names[0]= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.slave-data-source-names[1]= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.slave-data-source-names[x]= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.load-balance-algorithm-class-name= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.load-balance-algorithm-type= #详见读写分离部分

spring.shardingsphere.props.sql.show= #是否开启SQL显示,默认值: false
spring.shardingsphere.props.executor.size= #工作线程数量,默认值: CPU核数

3.数据分片流程解析

sharding-jdbc主要执行流程如下

spring加载执行流程梳理

实际使用时主要关注

  • max.connection.size.per.query的配置(执行和初始化阶段都会有影响)
  • 尽量使用预编译(解析sql时使用)
  • 有绑定关系的表应该配置上
  • 查询时尽量避免出现内存归并的方式导致OOM
  • 如果当前链接已开启事务,执行时会串行执行
  • 使用hint方式,确保分片时路由时HitManager有值,否则无法走到分片逻辑(异步时候注意)

解析引擎

  • org.apache.shardingsphere.sql.parser.SQLParserEngine#parse 

路由引擎

  • org.apache.shardingsphere.sharding.route.engine.ShardingRouteDecorator#decorate 生成分片路由结果
  • org.apache.shardingsphere.sharding.route.engine.ShardingRouteDecorator#getShardingConditions 路由信息
  • org.apache.shardingsphere.sharding.route.engine.type.standard.ShardingStandardRoutingEngine#route 根据数据节点组装的路由逻辑

改写引擎

  • org.apache.shardingsphere.sharding.rewrite.context.ShardingSQLRewriteContextDecorator#decorate 参数重写、添加重写各种场景重写方法
  • org.apache.shardingsphere.underlying.rewrite.sql.token.generator.SQLTokenGenerators#generateSQLTokens 解析statement,生成重写所需要的token
  • org.apache.shardingsphere.underlying.pluggble.prepare.BasePrepareEngine#rewrite(org.apache.shardingsphere.underlying.rewrite.context.SQLRewriteContext) 根据token生成返回改写后需要执行的sql,库表信息

执行引擎

  • org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement#initPreparedStatementExecutor 初始化
    • org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor#obtainExecuteGroups 获取具体的链接,这一步会确认链接模式
      • org.apache.shardingsphere.sharding.execute.sql.prepare.SQLExecutePrepareTemplate#getSynchronizedExecuteUnitGroups
        • org.apache.shardingsphere.sharding.execute.sql.prepare.SQLExecutePrepareTemplate#getSQLExecuteGroups 具体在这里判断,会根据分组结果获取链接
          • org.apache.shardingsphere.shardingjdbc.jdbc.adapter.AbstractConnectionAdapter#getConnections 获取链接的逻辑,注意数据源配置的链接数是否满足单次执行的链接数,否则可能出现等待假死情况
  • org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor#execute 执行
  • org.apache.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor#executeQuery 查询,会用到链接模式来确定流式还是内存

归并引擎

  • org.apache.shardingsphere.sharding.merge.ShardingResultMergerEngine#newInstance 选择归并类型
    • org.apache.shardingsphere.sharding.merge.dql.ShardingDQLResultMerger#merge DML归并
      • org.apache.shardingsphere.sharding.merge.dql.ShardingDQLResultMerger#build 各归并场景处理 
      • org.apache.shardingsphere.sharding.merge.dql.ShardingDQLResultMerger#decorate 分页装饰器

总结

分片数据功能里用了比较多的设计模式,如装饰器、工厂、委托、模版、发布-订阅、建造者、上下文等,整体代码、流程设计很优秀,值得学习,里面还有许多实现细节还有没有分析到,比如事务,sql解析,归并,各类上下文等,只是把大概的流程梳理了一下,整理出使用时需要注意的点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win10系统下安装qt5.12.0软件

一、软件下载 1、Qt开源社区下载 下载地址&#xff1a;https://download.qt.io/archive/qt/5.12/5.12.10/qt-opensource-windows-x86-5.12.10.exe 社区地址&#xff1a; Index of /archive/qt/5.12/5.12.10 2、百度网盘下载 链接&#xff1a;https://pan.baidu.com/s/1Sqi…

举例说明什么是卷积计算

卷积计算是一种数学运算&#xff0c;主要用于信号处理、图像处理等领域。它涉及到两个函数&#xff08;通常称为信号和核&#xff09;的互相关运算。在图像处理中&#xff0c;卷积计算通常用于实现图像的平滑、锐化、边缘检测等操作。 以图像处理为例&#xff0c;我们可以用一个…

【面试题24】MySQL如何给一个1000万的表安全的加字段

文章目录 一、前言二、MySQL表添加字段的方案2.1 ALTER TABLE 添加字段2.2 Online Alter Table2.3 Percona Toolkit2.4 给表新增字段2.5 使用触发器添加字段 总结 一、前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP面试专区。 计划将全覆盖PHP开发领域所有的面试题&#xf…

【AIGC】18、MobileSAM | 首个专为移动端设计的更快的 SAM

文章目录 一、背景二、方法2.1 耦合蒸馏2.2 从半蒸馏到解耦蒸馏 三、效果 论文&#xff1a;FASTER SEGMENT ANYTHING: TOWARDS LIGHTWEIGHT SAM FOR MOBILE APPLICATIONS 代码&#xff1a;https://github.com/ChaoningZhang/MobileSAM 出处&#xff1a;韩国庆熙大学 时间&am…

MP4视频格式和mp4v2的移植

目录 1、视频文件 2、MP4 3、MP4学习方法 4、MP4文件格式解析 5、MP4Info工具使用 6、mp4v2移植和播放 6.1、下载mp4v2 6.2、配置并编译 6.3、部署 6.4、编译sample 6.5、准备TF卡 6.6、运行和测试 7、MP4打包源码解析 8.添加网络telnet调试 8.1、为什么添加teln…

java进程注入

本文重点java Instrumentation java Instrumentation指的是可以用独立于应用程序之外的代理&#xff08;agent&#xff09;程序来监测和协助运行在JVM上的应用程序。这种监测和协助包括但不限于获取JVM运行时状态&#xff0c;替换和修改类定义等。简单一句话概括下&#xff1a;…

11 通信的基本概念

目录 通信分类概览 串行通讯与并行通讯 全双工、半双工及单工通讯 同步通讯与异步通讯 通讯速率 注意 通信分类概览 串行通讯与并行通讯 串行通讯是指设备之间通过少量数据信号线(一般是 8 根以下)&#xff0c;地线以及控制信号线&#xff0c;按数据位形式一位一位地传输…

Windows下创建进程的理解

创建windows进程&#xff0c;需要考虑两个点&#xff0c;即session和权限问题。了解这两点&#xff0c;网络上服务创建界面进程&#xff0c;管理员权限进程创建普通权限进程的代码则很好理解。 1、基础知识 (1) session (2) 权限 CreateProcessAsUser需要传入一个token&#x…

LeetCode 打卡day45--完全背包问题之最小填充次数

一个人的朝圣 — LeetCode打卡第45天 知识总结Leetcode 70. 爬楼梯题目说明代码说明 Leetcode 322. 零钱兑换题目说明代码说明 Leetcode 279. 完全平方数题目说明代码说明 知识总结 今天的问题都可以归结一句话, 在完全背包的问题设置下, 问将该背包填满最少需要放几件物品. L…

java基础(并发编程)-异步模式之生产者/消费者

一、定义要点 与前面的保护性暂停中的GuardedObject不同&#xff0c;不需要产生结果和消费结果的线程一一对应消费队列可以用来平衡生产和消费的线程资源生产者仅负责产生结果数据&#xff0c;不关心数据该如何处理&#xff0c;而消费者专心处理结果数据消息队列是有容量限制的…

代码随想录算法训练营第17期第1天 | 704. 二分查找、27. 移除元素

从头开始&#xff0c;重新再来&#xff0c;但是又不完全一样&#xff0c;之前是擅长的python&#xff0c;现在是C&#xff0c;能坚持下来么&#xff1f; 704. 二分查找 704. 二分查找https://leetcode.cn/problems/binary-search/ 上次写这道题已经是两个月之前&#xff0c;说…

Openresty原理概念篇(七)OpenResty 中用到的 NGINX 知识

一 OpenResty 中用到的 NGINX 知识 Luaj 是一个 Java 的 Lua 解释器,基于 Lua 5.2.x 版本 luaj ① 说明 1) 本文可有可无原因&#xff1a;如果你之前没有接触过nginx或者涉及一点nginx,那么建议阅读2) 由于自己已经对nginx整个脉络体系进行讲解,本文只是机械的摘录,构成…

Java使用RabbitMQ实战,Springboot使用rabbitMQ实战

文章目录 一、Java原生API1、简单实例2、延迟消息3、消费端限流4、消息属性设置5、消息可靠投递 二、Spring-API1、简单实例&#xff08;1&#xff09;引入rabbitMQ.xml&#xff08;2&#xff09;生产者&#xff08;3&#xff09;消费者&#xff08;4&#xff09;测试类 三、Sp…

使用VSCODE跑orbslam2踩的坑

我用的是ubuntu22.04&#xff0c;opencv是4.7&#xff0c;使用其他的库感觉就算版本不一样&#xff0c;也能跑。 一、运行build.sh能够产生可执行文件遇到的问题 1.由于opencv版本高带来的问题 这些问题怎么定位出现在哪些文件中&#xff0c;你通过命令行&#xff0c;运行下…

更灵活的CSS3新特性:帮你简化样式管理和优化网站性能

文章目录 I. 前言&#xff1a;介绍CSS3的进化和发展趋势CSS3的历史和版本CSS3的标准化和浏览器支持情况 II. 新的CSS选择器&#xff1a;扩展选择器的功能属性选择器&#xff1a;更多方式选择元素伪类和伪元素&#xff1a;更方便地定义样式 III. 改进的排版和布局&#xff1a;实…

在 EulerOS 系统中设置 Chrony 时间同步服务

以下是在 EulerOS 系统中设置 Chrony 时间同步服务的所有步骤。 1.查看系统版本 [rootservice11 ~]# cat /etc/redhat-release EulerOS release 2.0 (SP5)2.检查是否已安装chrony软件 [rootservice11 ~]# rpm -qa|grep chrony chrony-3.2-2.eulerosv2r7.x86_64如果没有安装…

Openlayers实战教程学习大纲及引导

本系列教程是Openlayers的实战教程&#xff0c;介绍Openlayes的一些基础知识&#xff0c;并重点讲述哪些地方是openlayers项目中常用的&#xff0c;给出具体示例&#xff0c;起到一个很好的引导学习作用。 版本说明 Openlayers的实战教程 分为**图文版** 和 **视频版**&#x…

【经验分享】全志科技官方Ubuntu16.04根文件系统镜像的替换和测试方法

本文主要基于全志A40i开发板——TLA40i-EVM&#xff0c;一款基于全志科技A40i处理器设计的4核ARM Cortex-A7高性能低功耗国产评估板&#xff0c;演示Ubuntu根文件系统镜像的替换和测试方法。 创龙科技TLA40i-EVM评估板接口资源丰富&#xff0c;引出双路网口、双路CAN、双路USB…

7.5_1散列查找(上)

基于一种数据结构&#xff1a; 散列表&#xff08;Hash Table&#xff09;&#xff0c;又称作哈希表 特点&#xff1a;数据元素的关键字与其存储地址直接相关 其实这个散列表也是基于数组实现的 加入19对13取余 加入再次插入1的话&#xff0c;塞不进去 数据元素不会直接存放到…

深入浅出设计模式 - 适配器模式

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…