Java-分布式框架-ShardingSphere

一、基本介绍

ShardingSphere定位为关系型数据库中间件

image.png
功能列表
功能列表 数据分片 分布式事务 数据库治理
- 分库 & 分表 标准化事务接口 配置动态化
- 读写分离 XA强一致事务 编排 & 治理
- 分片策略定制化 柔性事务 数据脱敏
- 无中心化分布式主键 可视化链路追踪
核心三套件
Sharding-JDBC Sharding-Proxy Sharding-Sidecar
数据库 任意 MySQL MySQL
连接消耗数
异构语言 仅Java 任意 任意
性能 损耗低 损耗略高 损耗低
无中心化
静态入口
Sharding-JDBC

客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC驱动,完全兼容JDBC和各种ORM框架。

  • 适用于任何基于JDBC的ORM框架:JPA, Hibernate, Mybatis, Spring JDBC Template或直 接使用JDBC。
  • 支持任何第三方的数据库连接池:DBCP, C3P0, BoneCP, Druid, HikariCP等。
  • 支持任意实现JDBC规范的数据库。支持MySQL,Oracle,SQLServer,PostgreSQL等遵循 SQL92标准的数据库。
image.png
Sharding-Proxy

透明化的数据库代理端,兼容所有MySQL/PostgreSQL协议的访问客户端。

  • 向应用程序完全透明,可直接当做MySQL/PostgreSQL使用。
  • 适用于任何兼容MySQL/PostgreSQL协议的的客户端。
image.png

二、核心概念

逻辑表

水平拆分的数据库(表)的相同逻辑和数据结构表的总称。例:订单数据根据主键尾数 拆分为10张表,分别是t_order_0到t_order_9,他们的逻辑表名为t_order。

真实表

在分片的数据库中真实存在的物理表。即上个示例中的t_order_0到t_order_9。

数据节点

数据分片的最小单元。由数据源名称和数据表组成,例:ds_0.t_order_0。

绑定表

分片规则一致的主表和子表。例如:t_order表和t_order_item表,均按照order_id分 片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联 查询效率将大大提升。

广播表

指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。 适用于数据量不大且需要与海量数据的表进行关联查询的场景。字典表就是典型的场景。

三、ShardingSphere快速启动

引入项目依赖
<dependencies> 
  <!‐‐ springboot‐‐> 
  <dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring‐boot‐starter‐web</artifactId>
    <version>2.0.5.RELEASE</version> 
  </dependency> 
  <!‐‐ mybatis ‐‐> 
  <dependency> 
    <groupId>org.mybatis.spring.boot</groupId> 
    <artifactId>mybatis‐spring‐boot‐starter</artifactId> 
    <version>2.0.1</version> 
    <exclusions> 
      <exclusion> 
        <artifactId>spring‐boot‐starter</artifactId>
        <groupId>org.springframework.boot</groupId> 
      </exclusion> 
    </exclusions> 
  </dependency> 
<!‐‐ shardingsphere‐jdbc,这里使用的版本为apache孵化版本,4.0之前 都是没有捐献给apache基金会的版本,之前的版本都在‐‐> 
<dependency> 
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>sharding‐jdbc‐spring‐boot‐starter</artifactId> 
  <version>4.0.0‐RC2</version> 
</dependency> 
<!‐‐ mysql 驱动 ‐‐> 
<dependency>  
  <groupId>mysql</groupId> 
  <artifactId>mysql‐connector‐java</artifactId> 
  <version>5.1.48</version> 
</dependency> 
<!‐‐ 可选,工具类 ‐‐> 
<dependency> 
  <groupId>org.projectlombok</groupId> 
  <artifactId>lombok</artifactId> 
  <version>1.16.20</version> 
  <scope>provided</scope>
 </dependency> 
</dependencies>
分库不分表配置
#配置ds0和ds1两个数据源,这里有个坑(使用下划线可能会有异常产生,字符不支持,如:ds_0)
spring.shardingsphere.datasource.names=ds0,ds1
#ds0配置
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
#数据库驱动
spring.shardingsphere.datasource.ds0.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc‐url=jdbc:mysql://192.168.241.198:3306/shop_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
#ds1配置
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
#数据库驱动
spring.shardingsphere.datasource.ds1.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc‐url=jdbc:mysql://192.168.241.198:3306/shop_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root
#分库策略根据id取模确定数据进哪个数据库
spring.shardingsphere.sharding.default‐database‐strategy.inline.sharding‐column=user_id
spring.shardingsphere.sharding.default‐database‐strategy.inline.algorithm‐expression=ds$‐>{user_id  %  2}
#绑定表
spring.shardingsphere.sharding.binding‐tables=t_order,t_order_item
#广播表
spring.shardingsphere.sharding.broadcast‐tables=t_address
#  t_order表策略
 
spring.shardingsphere.sharding.tables.t_order.actual‐data‐nodes=ds$‐>{0..1}.t_order
#使用SNOWFLAKE算法生成主键
spring.shardingsphere.sharding.tables.t_order.key‐generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key‐generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key‐
generator.props.worker.id=123
#  t_order_item表策略
spring.shardingsphere.sharding.tables.t_order_item.actual‐data‐nodes=ds$‐>{0..1}.t_order_item
#使用SNOWFLAKE算法生成主键
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.column=order_item_id
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.props.worker.id=123
分库分表
#配置ds0和ds1两个数据源
spring.shardingsphere.datasource.names=ds0,ds1
#ds0配置
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc‐url=jdbc:mysql://192.168.241.198:3306/shop_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
#ds1配置
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc‐url=jdbc:mysql://192.168.241.198:3306/shop_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root
 
#分库策略根据id取模确定数据进哪个数据库
spring.shardingsphere.sharding.default‐database‐strategy.inline.sharding‐column=user_id
spring.shardingsphere.sharding.default‐database‐strategy.inline.algorithm‐expression=ds$‐>{user_id  %  2}
#绑定表(好像没什么卵用)
spring.shardingsphere.sharding.binding‐tables=t_order,t_order_item
#广播表
spring.shardingsphere.sharding.broadcast‐tables=t_address
#具体分表策略
#节点    ds0.t_order_0,ds0.t_order_1,ds1.t_order_0,ds1.t_order_1
spring.shardingsphere.sharding.tables.t_order.actual‐data‐nodes=ds$‐>{0..1}.t_order_$‐>{0..1}
#分表字段id
spring.shardingsphere.sharding.tables.t_order.table‐strategy.inline.sharding‐column=order_id
#分表策略根据id取模,确定数据最终落在那个表中
spring.shardingsphere.sharding.tables.t_order.table‐strategy.inline.algorithm‐expression  =  t_order_$‐>{order_id  % 2}
#使用SNOWFLAKE算法生成主键
spring.shardingsphere.sharding.tables.t_order.key‐generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key‐generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key‐generator.props.worker.id=123
#节点    ds0.t_order_item_0,ds0.t_order_item_1,ds1.t_order_item_0,ds1.t_order_item_1
spring.shardingsphere.sharding.tables.t_order_item.actual‐data‐nodes=ds$‐>{0..1}.t_order_item_$‐>{0..1}
#分表字段id
spring.shardingsphere.sharding.tables.t_order_item.table‐strategy.inline.sharding‐column=order_id
#分表策略根据id取模,确定数据最终落在那个表中
spring.shardingsphere.sharding.tables.t_order_item.table‐strategy.inline.algorithm‐expression=t_order_item_$‐>{order_id  %  2}
#使用SNOWFLAKE算法生成主键
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.column=order_item_id
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.props.worker.id=123
读写分离
#shardingsphere读写分离,master‐slave,可以一主多从
spring.shardingsphere.datasource.names=ds‐master,ds‐slave0
#主库
spring.shardingsphere.datasource.ds‐master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds‐master.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds‐master.jdbc‐url=jdbc:mysql://192.168.241.198:3306/shop_ds_master?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds‐master.username=root
spring.shardingsphere.datasource.ds‐master.password=root
#从库0
spring.shardingsphere.datasource.ds‐slave0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds‐slave0.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds‐slave0.jdbc‐url=jdbc:mysql://192.168.241.199:3306/shop_ds_slave?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds‐slave0.username=root
spring.shardingsphere.datasource.ds‐slave0.password=root
#从库1
#spring.shardingsphere.datasource.ds‐slave1.type=com.zaxxer.hikari.HikariDataSource
#spring.shardingsphere.datasource.ds‐slave1.driver‐class‐name=com.mysql.jdbc.Driver
#spring.shardingsphere.datasource.ds‐slave1.jdbc‐url=jdbc:mysql://192.168.241.199:3306/shop_ds_slave1serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
#spring.shardingsphere.datasource.ds‐slave1.username=root
#spring.shardingsphere.datasource.ds‐slave1.password=root
#读写分离主从规则设置,当有2个以上从库时,从库读采用轮询的负载均衡机制(也可设置为随机读)
spring.shardingsphere.masterslave.load‐balance‐algorithm‐type=round_robin
spring.shardingsphere.masterslave.name=ds
spring.shardingsphere.masterslave.master‐data‐source‐name=ds‐master
#如果有多个从库,在本配置项后加:,ds‐slave1即可
spring.shardingsphere.masterslave.slave‐data‐source‐names=ds‐slave0
读写分离+分库分表
#shardingsphere读写分离,master‐slave,可以一主多从
spring.shardingsphere.datasource.names=ds‐master0,ds‐slave0,ds‐master1,ds‐slave1
#主库0
spring.shardingsphere.datasource.ds‐master0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds‐master0.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds‐master0.jdbc‐url=jdbc:mysql://192.168.241.198:3306/shop_ds_master?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds‐master0.username=root
spring.shardingsphere.datasource.ds‐master0.password=root
#从库0
spring.shardingsphere.datasource.ds‐slave0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds‐slave0.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds‐slave0.jdbc‐url=jdbc:mysql://192.168.241.199:3306/shop_ds_slave?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds‐slave0.username=root
spring.shardingsphere.datasource.ds‐slave0.password=root
#主库1
spring.shardingsphere.datasource.ds‐master1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds‐master1.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds‐master1.jdbc‐url=jdbc:mysql://192.168.241.198:3306/shop_ds_master1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds‐master1.username=root
spring.shardingsphere.datasource.ds‐master1.password=root
#从库1
spring.shardingsphere.datasource.ds‐slave1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds‐slave1.driver‐class‐name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds‐slave1.jdbc‐url=jdbc:mysql://192.168.241.199:3306/shop_ds_slave1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF‐8
spring.shardingsphere.datasource.ds‐slave1.username=root 
spring.shardingsphere.datasource.ds‐slave1.password=root
#分库策略根据id取模确定数据进哪个数据库
spring.shardingsphere.sharding.default‐database‐strategy.inline.sharding‐column=user_id
spring.shardingsphere.sharding.default‐database‐strategy.inline.algorithm‐expression=ds_$‐>{user_id  %  2}
#绑定表
sharding.jdbc.config.sharding.binding‐tables=t_order,t_order_item
spring.shardingsphere.sharding.broadcast‐tables=t_address
#分表策略
spring.shardingsphere.sharding.tables.t_order.actual‐data‐nodes=ds_$‐>{0..1}.t_order_$‐>{0..1}
spring.shardingsphere.sharding.tables.t_order.table‐strategy.inline.sharding‐column=order_id
spring.shardingsphere.sharding.tables.t_order.table‐strategy.inline.algorithm‐expression=t_order_$‐>{order_id  %  2}
spring.shardingsphere.sharding.tables.t_order.key‐generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key‐generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key‐generator.props.worker.id=123
spring.shardingsphere.sharding.tables.t_order_item.actual‐data‐nodes=ds_$‐>{0..1}.t_order_item_$‐>{0..1}
spring.shardingsphere.sharding.tables.t_order_item.table‐strategy.inline.sharding‐column=order_id
spring.shardingsphere.sharding.tables.t_order_item.table‐strategy.inline.algorithm‐expression=t_order_item_$‐>{order_id  %  2}
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.column=order_item_id
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key‐generator.props.worker.id=123
#读写分离数据源0
spring.shardingsphere.sharding.master‐slave‐rules.ds_0.master‐data‐source‐name=ds‐master0
spring.shardingsphere.sharding.master‐slave‐rules.ds_0.slave‐data‐source‐names=ds‐slave0
#读写分离主从规则设置,当有2个以上从库时,从库读采用轮询的负载均衡机制
spring.shardingsphere.sharding.master‐slave‐rules.ds_0.load‐balance‐algorithm‐type=ROUND_ROBIN
 
#读写分离数据源1
spring.shardingsphere.sharding.master‐slave‐rules.ds_1.master‐data‐source‐name=ds‐master1
spring.shardingsphere.sharding.master‐slave‐rules.ds_1.slave‐data‐source‐names=ds‐slave1
#读写分离主从规则设置,当有2个以上从库时,从库读采用轮询的负载均衡机制
spring.shardingsphere.sharding.master‐slave‐rules.ds_1.load‐balance‐algorithm‐type=ROUND_ROBIN

四、源码

程序分区块
名称 作用
sharding-core sharding内核模块;定义了核心api,SQL解析,SQL重写,SQL路由,spi,引擎等等核心功能sharding-distribution
sharding-distribution 部署、运维相关zip包中的代码
sharding-integration-test 整合测试
sharding-jdbc app-分库分表jdbc增强
sharding-opentracing 应用性能监控
sharding-orchestration 数据库编排治理
sharding-proxy 服务端代理分库分表模块
sharding-spring 与spring集成
sharding-sql-test SQL测试用例
sharding-transaction 分布式事务
image.png
shardingsphere-分库分表底层SQL执行过程分析.jpg

五、其它

  • sharding-jdbc:主要应用于应用层,目前只支持Java。
  • sharding-proxy:主要应用于db代理层,目前只支持Mysql数据库,类似于Mycat,与zookeeper结合使用能实现动态配置管理。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容