前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >sharding-sphere源码分析之基础应用篇

sharding-sphere源码分析之基础应用篇

作者头像
山行AI
发布2019-07-30 18:55:34
2.5K0
发布2019-07-30 18:55:34
举报
文章被收录于专栏:山行AI山行AI

做数据库分库分表的中间件有很多,如mycat、DRDS、TDDL等,它们的实现方式大多是作为一个数据库代理,是一个实现了MySQL协议的服务器。而sharding-sphere是一款开源的可以轻量级地像使用mysql-jdbc-connector那样来操作分库分表数据。同时它也提供了proxy模块,提供了代理的功能。而且它的orchestration模块提供了更加高级的数据管理功能。

本篇主要介绍一下sharding-sphere官方demo介绍的几种使用示例。

下载sharding-sphere-example-dev模块

进入sharding-spring-boot-mybatis-example模块,先来通过boot和mybatis整合版本整理下基本功能: 关于springboot autoconfigure部分,看下面的sharding-jdbc-spring-boot-starter的截图:

这部分不再多说,无非就是通过springboot starter加载dataSource和ShardingRule和一些基本信息。

功能分析

看下该模块下的配置文件:

我们可以看到在sharding data方面的常用功能是:

  • sharding databases
  • sharding tables
  • sharding databases and tables
  • master-slave
  • sharding & master-slave

我们来一一分析。

sharding-databases

  1. 将模块中的application.properties中的spring.profiles.active=sharding-databases,设置成分库模式,
  2. 对应的application-sharding-databases.properties中配置为:
代码语言:javascript
复制
spring.shardingsphere.datasource.names=ds_0,ds_1

spring.shardingsphere.datasource.ds_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_0.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_0.username=root
spring.shardingsphere.datasource.ds_0.password=

spring.shardingsphere.datasource.ds_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_1.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_1.username=root
spring.shardingsphere.datasource.ds_1.password=

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.tables.t_order.actual-data-nodes=ds_$->{0..1}.t_order
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
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
  • default-database-strategy.inline.sharding-column=user_id表示按user_id进行分片。
  • default-database-strategy.inline.algorithm-expression=ds_$->{user_id % 2}这里配置的是分库的策略。
  • 这段配置主要是分库模式的,会将数据按照对应的策略存入不同的库中去。上面配置的两个库的名字分别是ds_0和ds_1,分片算法的分片键是user_id,分片算法是对user_id 取模算法,user_id % 2。数据会根据算法插入到ds_0和ds_1两个库中去。

3. 我们看下这个example的执行过程:

代码语言:javascript
复制
@ComponentScan("org.apache.shardingsphere.example.common.mybatis")
@MapperScan(basePackages = "org.apache.shardingsphere.example.common.mybatis.repository")
@SpringBootApplication(exclude = JtaAutoConfiguration.class)
public class SpringBootMybatisMain {

    public static void main(final String[] args) {
        try (ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootMybatisMain.class, args)) {
            CommonService commonService = applicationContext.getBean(SpringPojoService.class);
            commonService.initEnvironment();
            commonService.processSuccess();
            commonService.cleanEnvironment();
        }
    }
}

这里我们主要关注下插入的流程(代码中注释掉删除数据和表的逻辑),看下SpringPojoServiceImpl中的insertData方法:

这个方法是向库中插入了10条数据,user_id的取值为1-10,我们看看插入的结果:

demo_ds_0对应配置中的ds_0,结果为:

demo_ds_1对应配置中的ds_1,结果为:

其中t_order_item表中的情况和t_order的情况一样,都是user_id为偶数的数据进入了demo_ds_0库对应的表中,user_id为奇数的数据进入到了demo_ds_1库中。

example中对应的删除数据的逻辑也与插入数据一样,不再多说。

sharding tables

  1. 修改配置:
  1. 数据库中的分表方案,对应的application-sharding-tables.properties中对应的配置为:
代码语言:javascript
复制
spring.shardingsphere.datasource.names=ds

spring.shardingsphere.datasource.ds.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds.jdbc-url=jdbc:mysql://localhost:3306/demo_ds?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=

spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds.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.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

关于配置:

  • spring.shardingsphere.datasource.names配置的是需要sharding的数据库名称,对应的是下面配置的库demo_ds;
  • actual-data-nodes=ds.t_order_$->{0..1}表示是对ds这个库进行分表,可以看到这里没有配置分库策略;
  • sharding-column=order_id和table-strategy.inline.algorithm-expression=t_order_$->{order_id % 2}表示是按order_id对表进行分片,分片规则是对2取余,也就是奇偶分片,order_id为奇数的数据进入t_order_1表,偶数的进入t_order_0表。
  • t_order_item为前缀的表的规则和t_order为前缀的表的规则一样。
  • key-generator部分是主键生成策略的配置。
  1. 我们主要关注插入数据的逻辑(删除的逻辑与插入数据的路由规则相同),先注释掉代码中的清数据的逻辑,运行org.apache.shardingsphere.example.sharding.spring.boot.mybatis.SpringBootMybatisMain之后,结果如下:

其中t_order_item与t_order的情况相同。可以看到在这种sharding方式下,是将数据在同一个库中进行分表存储的。

sharding databases and tables

  1. 修改配置
  1. application-sharding-databases-tables.properties中的配置内容为:
代码语言:javascript
复制
spring.shardingsphere.datasource.names=ds_0,ds_1

spring.shardingsphere.datasource.ds_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_0.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_0.username=root
spring.shardingsphere.datasource.ds_0.password=

spring.shardingsphere.datasource.ds_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_1.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_1.username=root
spring.shardingsphere.datasource.ds_1.password=

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.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

关于配置:

  • spring.shardingsphere.datasource.names=ds_0,ds_1是目前使用的库是ds_0,ds_1与下面配置的dataSource相对应。
  • default-database-strategy.inline.sharding-column.sharding-column=user_id表示以user_id为库分片键,default-database-strategy.inline.algorithm-expression=ds_$->{user_id % 2}表示按奇偶策略来划分库。
  • actual-data-nodes=ds_$->{0..1}.t_order_$->{0..1} 配置同时进行分库分表的格式。
  • t_order.table-strategy.inline.sharding-column=order_id配置t_order表的表分片键,t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id % 2}配置t_order的表分片策略。
  • key-generator部分是配置主键生成策略。

master-slave

主从模式

  1. 修改配置
  1. application-master-slave.properties的配置信息
代码语言:javascript
复制
spring.shardingsphere.datasource.names=ds_master,ds_slave_0,ds_slave_1

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://localhost:3306/demo_ds_master?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_master.username=root
spring.shardingsphere.datasource.ds_master.password=123456

spring.shardingsphere.datasource.ds_slave_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_slave_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_slave_0.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_slave_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_slave_0.username=root
spring.shardingsphere.datasource.ds_slave_0.password=123456

spring.shardingsphere.datasource.ds_slave_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_slave_1.jdbc-url=jdbc:mysql://localhost:3306/demo_ds_slave_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_slave_1.username=root
spring.shardingsphere.datasource.ds_slave_1.password=123456

spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin
spring.shardingsphere.masterslave.name=ds_ms
spring.shardingsphere.masterslave.master-data-source-name=ds_master
spring.shardingsphere.masterslave.slave-data-source-names=ds_slave_0,ds_slave_1
  • 配置了三个数据源,一主两从。
  • 从库的负载方式配置为round_robin。
  • 其中主从库数据的复制需要自己解决,可以采用mysql官方的主从复制方案可者使用第三方的读取binlog的中间件如阿里开源的canal等。
  1. 数据插入部分的执行结果:
  1. 可见数据在程序中是写入主库的,查询的时候是可以按照配置的从库负载方式在从库间进行路由的,当然也可以强制走主库,关于这些在之前的一篇文章(sharding-jdbc源码之读写分离和从库负载)中已经详细介绍过,有不明白的可以去翻阅。

sharding & master-slave

主从模式下的分片

  1. 修改配置
  1. application-sharding-master-slave.properties中的配置
代码语言:javascript
复制
spring.shardingsphere.datasource.names=ds_master_0,ds_master_1,ds_master_0_slave_0,ds_master_0_slave_1,ds_master_1_slave_0,ds_master_1_slave_1

spring.shardingsphere.datasource.ds_master_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_0.jdbc-url=jdbc:mysql://localhost:3306/ds_master_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_master_0.username=root
spring.shardingsphere.datasource.ds_master_0.password=123456

spring.shardingsphere.datasource.ds_master_0_slave_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_0_slave_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_0_slave_0.jdbc-url=jdbc:mysql://localhost:3306/ds_master_0_slave_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_master_0_slave_0.username=root
spring.shardingsphere.datasource.ds_master_0_slave_0.password=123456
spring.shardingsphere.datasource.ds_master_0_slave_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_0_slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_0_slave_1.jdbc-url=jdbc:mysql://localhost:3306/ds_master_0_slave_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_master_0_slave_1.username=root
spring.shardingsphere.datasource.ds_master_0_slave_1.password=123456

spring.shardingsphere.datasource.ds_master_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_1.jdbc-url=jdbc:mysql://localhost:3306/ds_master_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_master_1.username=root
spring.shardingsphere.datasource.ds_master_1.password=123456

spring.shardingsphere.datasource.ds_master_1_slave_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_1_slave_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_1_slave_0.jdbc-url=jdbc:mysql://localhost:3306/ds_master_1_slave_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_master_1_slave_0.username=root
spring.shardingsphere.datasource.ds_master_1_slave_0.password=123456
spring.shardingsphere.datasource.ds_master_1_slave_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_1_slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_1_slave_1.jdbc-url=jdbc:mysql://localhost:3306/ds_master_1_slave_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds_master_1_slave_1.username=root
spring.shardingsphere.datasource.ds_master_1_slave_1.password=123456

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.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

spring.shardingsphere.sharding.master-slave-rules.ds_0.master-data-source-name=ds_master_0
spring.shardingsphere.sharding.master-slave-rules.ds_0.slave-data-source-names=ds_master_0_slave_0, ds_master_0_slave_1
spring.shardingsphere.sharding.master-slave-rules.ds_1.master-data-source-name=ds_master_1
spring.shardingsphere.sharding.master-slave-rules.ds_1.slave-data-source-names=ds_master_1_slave_0, ds_master_1_slave_1

关于配置:

  • 总共配置了6个数据源,两个master分别各自对应两个slave。
  • 其中主从库数据的复制需要自己解决,可以采用mysql官方的主从复制方案可者使用第三方的读取binlog的中间件如阿里开源的canal等。
  • 真正的sharding是针对两个master来的,然后master中的数据会使用用户选择的数据同步方案复制到slave库中。
  • 对两个master库的sharding方式为:
代码语言:javascript
复制
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds_$->{user_id % 2}

通过user_id为分片键,按奇偶分库。

  • 对两个master库进行分表的配置为:
代码语言:javascript
复制
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}

分片键为order_id,方式为奇偶分表。

3. 对于数据写入的执行结果:

可以看到先是根据userid进行分库,然后对应库中再按orderid进行分表。

结语

到这里,关于sharding-sephere常用的分库分表使用示例都分析完毕了。下面总结几点:

  • sharding是大数据量下的一种常用处理方法,像elasticsearch、solrCloud、mongodb的分片模式等都是采用sharding的方式来处理大量数据的。
  • sharding一般是使用指定的分片键来进行分片路由的,sharding后数据处理的流程几乎都要经过解析->重写->路由->执行->结果归并这几个阶段。
  • sharding-sphere是支持针对数据库进行分库、分表、分片和读写分离处理等多种功能的中间件。
  • 它不同于mycat和DRDS这种中间代理服务转发处理数据库请求的中间件,它是比较轻量级直接在jdbc层和db交互的,使用它就像使用一种普通数据源一样简单。当然它目前的sharding-proxy模块也提供了代理的功能。

如果只是应用的话,本篇就基本上够用了。接下来会对上面的example中的这几种方式从源码角度进行分析,针对每个example的解析->重写->路由->执行->结果归并这几个阶段都会进行详细讲述。

参考

https://github.com/apache/incubator-shardingsphere

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发架构二三事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 下载sharding-sphere-example-dev模块
  • 功能分析
    • sharding-databases
      • sharding tables
        • sharding databases and tables
          • master-slave
            • sharding & master-slave
            • 结语
            • 参考
            相关产品与服务
            数据库
            云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档