ShardingSphere分库分表

article/2025/10/27 16:32:48

ShardingSphere是一款起源于当当网内部的应用框架。2015年在当当网内部诞生,最初就叫ShardingJDBC。2016年的时候,由其中一个主要的开发人员张亮,带入到京东数科,组件团队继续开发。在国内历经了当当网、电信翼支付、京东数科等多家大型互联网企业的考验,在2017年开始开源。并逐渐由原本只关注于关系型数据库增强工具的ShardingJDBC升级成为一整套以数据分片为基础的数据生态圈,更名为ShardingSphere。到2020年4月,已经成为了Apache软件基金会的顶级项目。

ShardingSphere包含三个重要的产品,ShardingJDBC、ShardingProxy和ShardingSidecar。其中sidecar是针对service mesh定位的一个分库分表插件,目前在规划中。而我们今天学习的重点是ShardingSphere的JDBC 。

​其中,ShardingJDBC是用来做客户端分库分表的产品,而ShardingProxy是用来做服务端分库分表的产品。

ShardingJDBC只是客户端的一个工具包,可以理解为一个特殊的JDBC驱动包,所有分库分表逻辑均由业务方自己控制,所以他的功能相对灵活,支持的数据库也非常多,但是对业务侵入大,需要业务方自己定制所有的分库分表逻辑。而ShardingProxy是一个独立部署的服务,对业务方无侵入,业务方可以像用一个普通的MySQL服务一样进行数据交互,基本上感觉不到后端分库分表逻辑的存在,但是这也意味着功能会比较固定,能够支持的数据库也比较少。这两者各有优劣。

ShardingJDBC

springboot项目pom引入

<!-- sharding 分库分表--><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency>

浅看一下源码,spring.factories引入了

org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration

spring.shardingsphere.enabled默认配置true

 这里还有一个注意点,@AutoConfigureBefore(DataSourceAutoConfiguration.class)

 在springboot配置类之前注入

数据源默认是第一个shardingDataSource(替换了springboot默认的实现类),因为下面几个condition都不满足,需要额外在配置文件里配置

springboot默认导入的数据源配置类是org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

可以看到条件已经不满足了,因为sharding配置类的优先级高,所以是先导入了自己的datasource,默认的也就没用了

 

核心概念

  • 逻辑表:水平拆分的数据库的相同逻辑和数据结构表的总称

  • 真实表:在分片的数据库中真实存在的物理表。

  • 数据节点:数据分片的最小单元。由数据源名称和数据表组成

  • 绑定表:分片规则一致的主表和子表。

  • 广播表:也叫公共表,指素有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中都完全一致。例如字典表。

  • 分片键:用于分片的数据库字段,是将数据库(表)进行水平拆分的关键字段。SQL中若没有分片字段,将会执行全路由,性能会很差。

  • 分片算法:通过分片算法将数据进行分片,支持通过=、BETWEEN和IN分片。分片算法需要由应用开发者自行实现,可实现的灵活度非常高。

  • 分片策略:真正用于进行分片操作的是分片键+分片算法,也就是分片策略。在ShardingJDBC中一般采用基于Groovy表达式的inline分片策略,通过一个包含分片键的算法表达式来制定分片策略,如t_user_$->{u_id%8}标识根据u_id模8,分成8张表,表名称为t_user_0到t_user_7。

ShardingJDBC的分片算法

ShardingSphere目前提供了一共五种分片策略:

  • NoneShardingStrategy

    不分片。这种严格来说不算是一种分片策略了。只是ShardingSphere也提供了这么一个配置。

  • InlineShardingStrategy

    最常用的分片方式

    • 配置参数: inline.shardingColumn 分片键;inline.algorithmExpression 分片表达式
    • 实现方式: 按照分片表达式来进行分片。
  • StandardShardingStrategy

    只支持单分片键的标准分片策略。

    • 配置参数:standard.sharding-column 分片键;standard.precise-algorithm-class-name 精确分片算法类名;standard.range-algorithm-class-name 范围分片算法类名

    • 实现方式:

      shardingColumn指定分片算法。

      preciseAlgorithmClassName 指向一个实现了io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm接口的java类名,提供按照 = 或者 IN 逻辑的精确分片 示例:com.roy.shardingDemo.algorithm.MyPreciseShardingAlgorithm

      rangeAlgorithmClassName 指向一个实现了 io.shardingsphere.api.algorithm.sharding.standard.RangeShardingAlgorithm接口的java类名,提供按照Between 条件进行的范围分片。示例:com.roy.shardingDemo.algorithm.MyRangeShardingAlgorithm

    • 说明:

      其中精确分片算法是必须提供的,而范围分片算法则是可选的。

  • ComplexShardingStrategy

    支持多分片键的复杂分片策略。

    • 配置参数:complex.sharding-columns 分片键(多个); complex.algorithm-class-name 分片算法实现类。

    • 实现方式:

      shardingColumn指定多个分片列。

      algorithmClassName指向一个实现了org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm接口的java类名。提供按照多个分片列进行综合分片的算法。示例:com.roy.shardingDemo.algorithm.MyComplexKeysShardingAlgorithm

  • HintShardingStrategy

    不需要分片键的强制分片策略。这个分片策略,简单来理解就是说,他的分片键不再跟SQL语句相关联,而是用程序另行指定。对于一些复杂的情况,例如select count(*) from (select userid from t_user where userid in (1,3,5,7,9)) 这样的SQL语句,就没法通过SQL语句来指定一个分片键。这个时候就可以通过程序,给他另行执行一个分片键,例如在按userid奇偶分片的策略下,可以指定1作为分片键,然后自行指定他的分片策略。

    • 配置参数:hint.algorithm-class-name 分片算法实现类。

    • 实现方式:

      algorithmClassName指向一个实现了org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm接口的java类名。 示例:com.roy.shardingDemo.algorithm.MyHintShardingAlgorithm

      在这个算法类中,同样是需要分片键的。而分片键的指定是通过HintManager.addDatabaseShardingValue方法(分库)和HintManager.addTableShardingValue(分表)来指定。

      使用时要注意,这个分片键是线程隔离的,只在当前线程有效,所以通常建议使用之后立即关闭,或者用try资源方式打开。

分片策略2个库,1个库2个表

分库策略和分表策略都是5种

 

 

## oms_order分片策略
## 节点 ds0.oms_order_0,ds0.oms_order_1,ds1.oms_order_0,ds1.oms_order_1
spring.shardingsphere.sharding.tables.oms_order.actual-data-nodes=ds$->{0..1}.oms_order_$->{0..1}
##分库策略
spring.shardingsphere.sharding.tables.oms_order.database-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.oms_order.database-strategy.inline.algorithm-expression=ds$->{id % 2}
## 分表策略
spring.shardingsphere.sharding.tables.oms_order.table-strategy.inline.sharding-column=id
## 注意下,对于除法,groovy会计算出浮点数,而不是整数。即 3/2=1.5,如果需要计算出整数 3.intdiv(2)=1
spring.shardingsphere.sharding.tables.oms_order.table-strategy.inline.algorithm-expression = oms_order_$->{((id+1) % 4).intdiv(2)}

ShardingProxy

hardingProxy目前只支持MySQL和PostgreSQL。并且,客户端连接ShardingProxy时,最好使用MySQL的JDBC客户端。下面我们来部署一个ShardingProxy服务。

ShardingProxy部署

从ShardingSphere官网下载4.1.1版本的ShardingProxy发布包apache-shardingsphere-4.1.1-sharding-proxy-bin.tar.gz,解压到本地目录。

首先,我们需要把MySQL的JDBC驱动包mysql-connector-java-8.0.20.jar手动复制到ShardingProxy的lib目录下。ShardingProxy默认只附带了PostgreSQL的JDBC驱动包,而不包含MySQL的JDBC驱动包。

然后到conf目录下,修改server.yaml,将配置文件中的authentication和props两段配置的注释打开。

在ShardingProxy中复制config-sharding.yaml配置:

schemaName: sharding_dbdataSources:ds:url: jdbc:mysql://localhost:3306/micromall?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword: rootds0:url: jdbc:mysql://localhost:3306/micromall_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword: rootds1:url: jdbc:mysql://localhost:3306/micromall_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword: rootshardingRule:tables:oms_order:actualDataNodes: ds$->{0..1}.oms_order_$->{0..1}databaseStrategy:inline:shardingColumn: idalgorithmExpression: ds$->{id % 2}tableStrategy:inline:shardingColumn: idalgorithmExpression: oms_order_$->{(id+1) % 4 /2}keyGenerator:column: idtype: SNOWFLAKEprops:worker.id: 123oms_order_item:actualDataNodes: ds$->{0..1}.oms_order_item_$->{0..1}databaseStrategy:inline:shardingColumn: order_idalgorithmExpression: ds$->{id % 2}tableStrategy:inline:shardingColumn: order_idalgorithmExpression: oms_order_item_$->{(order_id+1) % 4 / 2}keyGenerator:column: idtype: SNOWFLAKEprops:worker.id: 123bindingTables: - oms_order,oms_order_itemdefaultDataSourceName: ds

直接运行start.bat/start.sh脚本,默认占用的是3307端口。

在springboot怎么使用,启动类中排除之前导入的shardingjdbc配置类,就可以用默认的数据源配置了。

 

 

分库分表带来的问题

定制主键生成策略:主键是分库分表中非常重要的业务要素,通常分库分表都会采用主键来作为分片键,这个时候主键就不再只是用来提升查询效率了,还需要坚固数据分片的效率。要如何定制高效的主键生成策略?

很多SQL不支持:例如MySQL里会配for each标签来执行批量SQL,原始数据库是支持的,但是分库分表不支持。查询的SQL比较多时,路由策略是否支持?参见官网文档: SQL :: ShardingSphere 

其他问题:数据迁移、扩缩容(一开始就设计好了8张表,按id取模--x%8分片策略,突然表不够用要扩容成16张,怎么把数据迁移x%16)、公共表、读写分离、配置往注册中心集中配置

分布式事务处理:一旦涉及到分布式事务,就会带来非常多麻烦的事情


http://chatgpt.dhexx.cn/article/THuYquDr.shtml

相关文章

mysql innodb分表技术_mysql分表技术

一般来说&#xff0c;当我们的数据库的数据超过了100w记录的时候就应该考虑分表或者分区了&#xff0c;这次我来详细说说分表的一些方法。 目前我所知道的方法都是MYISAM的&#xff0c;INNODB如何做分表并且保留事务和外键&#xff0c;我还不是很了解。 首先&#xff0c;我们需…

mybatis实现分表

分析上面登陆&#xff0c;当前表按照年份分表了&#xff0c;最大的一张表超过500w建议分表 注意:之前写的经过多方测试发现遍历的时候参数传递不进去&#xff0c;现如今已经完善 package org.jeecg.config.mybatis;import lombok.extern.slf4j.Slf4j; import org.apache.ibati…

mysql 分表条件_mysql分表详解

本人混迹qq群2年多了&#xff0c;经常听到有人说“数据表太大了&#xff0c;需要分表”&#xff0c;“xxxx了&#xff0c;要分表”的言论&#xff0c;那么&#xff0c;到底为什么要分表&#xff1f; 难道数据量大就要分表&#xff1f; mysql数据量对索引的影响 本人mysql版本为…

ShardingSphere简介与分表使用

一、ShardingSphere简介 1、简介 ShardingSphere 已于 2020 年 4 月 16 日成为 Apache 软件基金会的顶级项目。 ShardingSphere 是一套开源的分布式数据库中间件解决方案。 ShardingSphere 产品定位为 Database Plus&#xff0c;旨在构建异构数据库上层的标准和生态圈。 它…

mysql mybatis分表查询_mybatis 自动分表

参考: 相关源码已上传至我的 github 欢迎转载,转载请注明出处,尊重作者劳动成果:https://www.cnblogs.com/li-mzx/p/9963312.html 前言 小弟才疏学浅,可能很多问题也没有考虑到,权当抛砖引玉,希望各位大神指点 项目背景: 希望做一个功能,能在sql操作数据库时,根据某个…

mysql 分区分表_mysql分库分区分表

一、分表 分表分为水平分表和垂直分表。 水平分表原理&#xff1a; 分表策略通常是用户ID取模&#xff0c;如果不是整数&#xff0c;可以首先将其进行hash获取到整。 水平分表遇到的问题&#xff1a; 1. 跨表直接连接查询无法进行 2. 我们需要统计数据的时候 3. 如果数据…

Mock平台介绍

Mock平台可以用来模拟接口&#xff0c;具备了get方法&#xff0c;post方法&#xff0c;header&#xff0c;cookie&#xff0c;重定向等功能。 Mock平台的搭建应用于mock框架&#xff0c;在github上可以下载到开源的代码。 下载地址&#xff1a;http://repo1.maven.org/maven2/…

Mock 框架 Moq 的使用

Intro# Moq 是 .NET 中一个很流vb.net教程行的 Mock 框架&#xff0c;使c#教程用 Mock 框架我python基础教程们可以只针对我java基础教程们关注的代码进行测试&#xff0c;对于sql教程依赖项使用 Mock 对象配置预期的依赖服务的行为。 Moq 是基于 Castle 的动态代理来实现的&…

mockjs入门

mockjs 1,mock.js是什么&#xff1f; mockjs是生成随机数据的一款前端工具&#xff0c;用来模拟 Ajax 请求&#xff0c;生成并返回模拟数据 2&#xff0c;为什么用mockjs&#xff1f; 当程序员做项目开发时&#xff0c;前端工程师要请求后端做好的数据时&#xff0c;有可能…

monkey简介

https://blog.csdn.net/lebang08/article/details/70858532 https://www.cnblogs.com/aland-1415/p/6949964.html https://blog.csdn.net/aisemi/article/details/55254348 一、Monkey 简介 monkey是Android SDK中自带的一个命令行工具&#xff0c;使用Java语言写成&#xf…

mokey的介绍和使用

一、monkey介绍 monkey是Android SDK提供的一个命令行工具&#xff0c;可以简单方便的发送伪随机的用户时间流&#xff0c;对Android APP做压力&#xff08;稳定性、健壮性&#xff09;测试。主要是为了测试APP是否存在无响应和崩溃的情况。 二、monkey的使用 1、前提条件&a…

APP测试— 测试工具mokey

文章目录 1 Mokey概念2 运行Monkey&#xff08;对手机进行300次无规律点击&#xff09;3 Mokey常规参数4 Monkey 事件类参数5 Monkey 约束类参数 1 Mokey概念 1&#xff09;Monkey是Android SDK提供的一个命令行工具&#xff0c;可以简单、方便的运行任何版本的Android模拟器和…

Kafka配置用户名密码访问

1 软件版本 kafka_2.12-2.4.0.tgz&#xff08;带zookeeper&#xff09; 2 kafka服务端部署 2.1 将安装包上传到服务器&#xff0c;并解压 tar zxvf kafka_2.12-2.4.0.tgz -C /datamv kafka_2.12-2.4.0 kafka2.2 修改kafka配置文件 server.properties vim /data/kafka/conf…

linux 用户名和密码的处理

1. 创建新用户和密码 # 创建用户 testuser useradd testuser# 给已创建的用户testuser设置密码 passwd testuser# 新创建的用户会在 /home 下创建一个用户目录testuser# 修改用户这个命令的相关参数 usermod --help# 删除用户testuser userdel testuser# 删除用户所在目录rm -…

用户名,密码登录

1.导入项目需要的依赖&#xff0c;分层 注意&#xff1a;如果你的数据库是5.5的版本&#xff0c;依赖要用低版本的&#xff0c;高版本不稳定&#xff0c;新增的内容不识别&#xff0c;会报各种各样奇葩的错误 2.创建实体类 它的属性要和数据库字段对应 package com.oa.entity…

实现用户输入用户名和密码登录

题目 实现用户输入用户名和密码登录&#xff0c;当用户名为admin或administrator且密码为666666时&#xff0c;显示“登录成功”&#xff0c;否则显示“登录失败”&#xff0c;登录失败时允许重复输入三次。 实例 参考程序 User1 "admin" User2 "administr…

计算机用户名和初始密码,电脑默认的用户名和密码是多少

优质回答 回答者&#xff1a;止树2018 电脑用户默认是没有密码的&#xff0c;除非你设置了&#xff0c;没有设置的前提下&#xff0c;直接按回车键就可以进系统了。 电脑默认的用户是administrator&#xff0c;如果你创建了自己的新用户名&#xff0c;那么&#xff0c;原始管理…

服务器密码以及用户名怎么修改

服务器密码以及用户名怎么修改 我是艾西&#xff0c;今天给大家说下服务器密码如何修改 windows2003系统&#xff1a; 1、右键我的电脑&#xff0c;点击“管理”&#xff1a; 2、在“本地用户和组”中打开“用户”&#xff0c;在右侧找到 Administrator 账户进行修改。 200…

电脑更改开机密码和用户名

一、电脑更改开机密码 1、快捷键CtrlAltDel出现以下界面。 2、点击“更改密码”&#xff0c;出现修改密码的界面&#xff0c;输入旧的密码&#xff0c;以及新的密码&#xff0c;确定即可。 二、电脑更改开机用户名 1、打开电脑的”控制面板“。 2、在控制面板中点击“用户帐户…

基于51单片机的呼吸灯程序编写

利用51单片机编写的呼吸灯小程序&#xff0c;实验程序内容截图分享~