4 Star 20 Fork 11

鹿痴 / mybatis-plus-sharding

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

demo地址:https://gitee.com/luci-fast/mybatis-plus-sharding

最近进行技术重构,考虑到服务拆分与分表分库,首先想到了mycat,毕竟mycat是代理,对于代码方面来说,能做到零侵入。 但是了解了一下发现mycat社区活跃度,与一些数据分区难点的解决方案,个人觉得都不是很理想,就又看了sharding sphere.

sharding sphere首先是轻量级的,而且对于java来说,只是多集成jar包,对jdbc,jpa,mybatis都支持,社区活跃度还高,便沉下心来看了几天, 发现代码侵入性真的很低很低,因此把这次集成过程记录下来

组件版本:

springboot 2.1.1

mysql5.7

mybatis-plus 国人开发的mybatis增强工具,集成使用简单,一直关注着,很赞的组件。链接:https://mp.baomidou.com/

shardingsphere jdbc 4.0.4-RC1  4.x版本是加入apache组织后的发布版本,有很多改动。

shardingsphere proxy 最新版本 用于开发运维工具,分表分库以后,对于数据的查询我们很难像单库单表一样迅速定位,简单来说就是, 使用navicat连接 shardingsphere proxy服务,这样就可以很方便直观的操作数据库,因为官方也介绍proxy性能损耗大,适合做运维工具。

shardingsphere官方链接: https://shardingsphere.apache.org/

集成过程

  • 1.分库分表依据

    因为架构是基于微服务的,所以每个服务有自己的数据库,根据每个服务的未来理想化的数据进行预估。每张表量在千万以下。
    比如:订单,预计一千亿数据,那么就分为32库,每个库72张表,最终一共两千多张表,一千亿数据平均下来,每张表只有几百亿。
    接下来 我们以订单相关的几张表为例,进行分表分库:订单表  订单明细表 订单字典表 订单子表(一些业务可能会有)
  • 2.分片相关概念

    逻辑表- 业务逻辑表。  例如:订单表o_order 订单明细表o_order_item  因为量大 都需要分库
    真实表- 真实的数据分片表。 例如:o_order23
    数据节点- 数据分片的最小单元。由数据源名称和数据表组成。例如: odb1.o_order23
    绑定表- 具有数据关联的表,建立绑定关系,则在一个库下,可以进行join。 例如:订单数据与订单明细,如果在一个库下,则可以join查询。
    广播表- 一些静态信息表。 广播分发到每一个数据源,方便查询join。例如:订单字典表。
    不分片表- 不需要分片的表。 例如:订单子表,一些业务订单,可能拆分成子订单,但这种情况少之又少,数据很小,无需分表分库。
    分片键- 进行分表分库的字段。 例如:根据商户id进行分库,根据订单id进行分表。
    分片算法- 例如:商户id取模36得到数据源 订单id取模72得到表
    分片策略- sphere提供了几种策略,这里采用最简单的行表达式
    分布式id- 使用内置的雪花算法,但是workid没有想好在docker环境下如何处理
    分布式事务- 使用内置xa支持
    sql支持与不支持- 请查看官方文档
    路由原理- 请查看官方文档 尤其是带不带分片键的区别
    以上概念均可在官方文档查看。接下来进行实际操作,实现对订单与订单明细表的36库72表
  • 3.创建数据库

    在mysql创建37个数据库 其中odb为默认数据源 存放不需要分片的表
    CREATE DATABASE `odb` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb0` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb1` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb2` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb3` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb4` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb5` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb6` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb7` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb8` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb9` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb10` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb11` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb12` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb13` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb14` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb15` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb16` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb17` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb18` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb19` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb20` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb21` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb22` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb23` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb24` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb25` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb26` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb27` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb28` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb29` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb30` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb31` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb32` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb33` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb34` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    CREATE DATABASE `odb35` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    设置最大连接数
    set GLOBAL max_connections=1000;
  • 4.导入pom

    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
        <version>4.0.0-RC1</version>
    </dependency>
    <!-- for spring namespace -->
    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>sharding-jdbc-spring-namespace</artifactId>
        <version>4.0.0-RC1</version>
    </dependency>
    其它包省略
  • 5.建立sharding规则

    spring:
      shardingsphere:
    	props:
    	  # 打印sql
    	  sql.show: true
    	  check:
    		table:
    		  metadata:
    			# 是否在启动时检查分表元数据一致性
    			enabled: false
    	datasource:
    	  # 数据源汇总
    	  names: odb,odb0,odb1,odb2,odb3,odb4,odb5,odb6,odb7,odb8,odb9,odb10,odb11,odb12,odb13,odb14,odb15,odb16,odb17,odb18,odb19,odb20,odb21,odb22,odb23,odb24,odb25,odb26,odb27,odb28,odb29,odb30,odb31,odb32,odb33,odb34,odb35
    	  # 真实数据源连接
    	  odb:
    		type: com.zaxxer.hikari.HikariDataSource
    		driver-class-name: com.mysql.jdbc.Driver
    		jdbcUrl: jdbc:mysql://localhost:3306/odb?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT&allowPublicKeyRetrieval=true
    		username: root
    		password: root
    	  odb0:
    		type: com.zaxxer.hikari.HikariDataSource
    		driver-class-name: com.mysql.jdbc.Driver
    		jdbcUrl: jdbc:mysql://localhost:3306/odb0
    		username: root
    		password: root
    		# 其中省略 1-34
    	  odb35:
    		type: com.zaxxer.hikari.HikariDataSource
    		driver-class-name: com.mysql.jdbc.Driver
    		jdbcUrl: jdbc:mysql://localhost:3306/odb35
    		username: root
    		password: root
    	# 分片规则
    	sharding:
    	  # 默认数据源
    	  default-data-source-name: odb
    	  # 默认主键生成策略
    	  default-key-generator:
    		type: SNOWFLAKE
    		column: id
    		worker:
    		  id: order # 雪花算法workid  还没想好多实例docker情况下如何配置
    		max:
    		  tolerate:
    			time:
    			  difference:
    				milliseconds: 1
    	  # 默认分库策略 根据门店id 取模 这样虽然做不到数据平均分摊,但是每个门店的订单都统一在一个库下,方便join。
    	  default-database-strategy:
    		inline:
    		  shardingColumn: shop_id
    		  algorithmExpression: odb$->{shop_id % 36}
    	  # 广播表
    	  broadcastTables:
    		- o_dict
    	  # 绑定表关系 分片策略相同的表,即可建立绑定关系
    	  bindingTables:
    		- o_order,o_order_item
    	  # 具体表策略
    	  tables:
    		# 订单表 根据订单id取模
    		o_order:
    		  actual-data-nodes: odb$->{0..35}.o_order$->{0..71}
    		  table-strategy:
    			inline:
    			  sharding-column: id
    			  algorithm-expression: o_order$->{id % 72}
    
    		#  订单表详情 根据订单id取模 
    		o_order_item:
    		  actual-data-nodes: odb$->{0..35}.o_order_item$->{0..71}
    		  table-strategy:
    			inline:
    			  sharding-column: order_id
    			  algorithm-expression: o_order_item$->{order_id % 72}
  • 6 建表

      项目中 orm框架去映射逻辑表,在执行sql时,会自动映射到真实物理表
      启动服务,就可以利用mybatis执行建表语句
       CREATE TABLE IF NOT EXISTS
      o_order (
      		id BIGINT AUTO_INCREMENT,
      		shop_id BIGINT NOT NULL,
      		code VARCHAR(50),
      		create_time timestamp(0),
      		PRIMARY KEY (id)
          );
      DROP TABLE IF EXISTS `o_order_child`;
      CREATE TABLE `o_order_child`  (
        `id` bigint(20) NOT NULL,
        `order_id` bigint(20) NULL DEFAULT NULL,
        `shop_id` bigint(20) NULL DEFAULT NULL,
        PRIMARY KEY (`id`) USING BTREE
      ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
    
      DROP TABLE IF EXISTS `o_dict`;
      CREATE TABLE `o_dict`  (
        `id` bigint(20) NOT NULL,
        `shop_id` bigint(20) NULL DEFAULT NULL,
        `key` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
        PRIMARY KEY (`id`) USING BTREE
      ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
      
      	CREATE TABLE
      	IF NOT EXISTS o_order_item (
      		id BIGINT AUTO_INCREMENT,
      		order_id BIGINT,
      		shop_id BIGINT NOT NULL,
      		NAME VARCHAR (50),
      		PRIMARY KEY (id)
      	);
      	然后会发现,odb0到odb35 每个库都有72张订单表,72张订单明细表。每个库都有一张字典表。odb中有子单表。
  • 6 sharding sphere proxy服务

      通过官方的docker拉取服务,总是启动失败,未找到原因。因此直接下载了最新的客户端。将分片规则copy进去。就可启动。
      默认端口3307 设置用户名密码  即可用navicat连接。
      连接成功后,即可进行运维操作。比如建表等等。但是发现并未显示不分库的表,不过sql可以正常执行。
  • 7 flyway继承

      失败,因为flyway默认会读取系统表的信息,而我们的sharding时jdbc代理的逻辑表,没有真实表
  • 8 读写分离

      未加入,可自行根据官方文档参考加入
  • 8 分库事务

       @Transactional配合TransactionTypeHolder.set(TransactionType.XA);即可实现。
       其实官方文档中有@ShardingTransactionType(TransactionType.LOCAL)注解,但本人未下载到相应jar包。
      	@Transactional(rollbackFor = Exception.class)
      	public void batchAdd() {
      		TransactionTypeHolder.set(TransactionType.XA);
      		for (int i=41;i<=60; i++) {
      			Order order  = new Order();
      			order.setId(new Long(i));
      			order.setShopId(new Long(i));
      			order.setCode(i + "test");
      			orderMapper.insert(order);
      			if (i == 50) {
      				throw new RuntimeException();
      			}
      			for(int j=1;j<=10; j++) {
      				OrderItem orderItem = new OrderItem();
      				orderItem.setId(new Long((i*10)+j));
      				orderItem.setOrderId(order.getId());
      				orderItem.setName("明细 "+ j);
      				orderItem.setShopId(new Long(i));
      				itemMapper.insert(orderItem);
      			}
      		}
      	}

demo地址:https://gitee.com/luci-fast/mybatis-plus-sharding

空文件

简介

mybatis-plus-shardingjdbc 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/luci-fast/mybatis-plus-sharding.git
git@gitee.com:luci-fast/mybatis-plus-sharding.git
luci-fast
mybatis-plus-sharding
mybatis-plus-sharding
master

搜索帮助