写点什么

框架整合(二)- 使用 Apache ShardingSphere 实现数据分片

作者:大菠萝蜜
  • 2022 年 8 月 04 日
  • 本文字数:2510 字

    阅读完需:约 8 分钟

框架整合(二)- 使用Apache ShardingSphere实现数据分片

最近公司项目中使用到了订单表,后续如果项目上线了可能订单数据较大,那么就需要对订单表进行分片或者分库操作,正好最近私下学习到了这里,就加以记录,方便以后项目使用。

解决方案
  • 实现分库分表的的解决方案


  1. Apache ShardingShpere(本博文选择的方案)

  2. Mycat

具体实现(分表)
  • 创建数据库(ds0)和表 t_order_0t_order_1


CREATE TABLE `t_order_0` (  `order_id` bigint(20) unsigned NOT NULL,  `user_id` int(11) DEFAULT NULL,  PRIMARY KEY (`order_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `t_order_1` ( `order_id` bigint(20) unsigned NOT NULL, `user_id` int(11) DEFAULT NULL, PRIMARY KEY (`order_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
复制代码



注: 分表时注意表的订单表的命名规则(分库同理),具有相同的名称后面的编号不同等


  • 创建 springboot 项目并结合 mybatis-plus


注:使用 mybatis-plus 是因为公司项目中使用的这个,方便以后的使用(当然也可使用其他 orm 框架,实现方法同理)


  • 引入项目依赖 shardingsphere(其他基础依赖略)


    <dependency>            <groupId>org.apache.shardingsphere</groupId>            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>            <version>5.0.0-alpha</version>        </dependency>
复制代码


  • application.properties 文件中加入 shardingsphere 配置


:可参考官方文档,但官方文档更新可能之后,目前文档是之前版本的,最新 5.0 版本似乎未及时更新(目前项目配置是本人亲测成功的)


  1. 配置中注释掉的配置是分库的相关配置

  2. 着重注意分片相关配置后面的值设置规则

  3. 当前分表策略(表字段 order_id),分表算法配置为取模


# 配置真实数据源spring.shardingsphere.datasource.names=ds0
spring.shardingsphere.datasource.common.type=com.zaxxer.hikari.HikariDataSourcespring.shardingsphere.datasource.common.driver-class-name=com.mysql.jdbc.Driverspring.shardingsphere.datasource.common.username=rootspring.shardingsphere.datasource.common.password= root
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost:3306/ds0?serverTimezone=UTC&useSSL=false#spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://localhost:3306/ds1?serverTimezone=UTC&useSSL=false
# 配置 t_order 表规则spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds0.t_order_$->{0..1}
# 配置分库策略#spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-column=user_id#spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-algorithm-name=database-inline
# 配置分表策略spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_idspring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=table-inline
# 配置 分片算法#spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE#spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds$->{user_id % 2}spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.type=INLINEspring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.props.algorithm-expression=t_order_$->{order_id % 2}
# 分布式序列策略配置spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=order_idspring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=snowflake
# 分布式序列算法配置spring.shardingsphere.rules.sharding.key-generators.snowflake.type =SNOWFLAKEspring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id =123spring.shardingsphere.props.sql-show=true
复制代码


  • 创建 order 实体类


:着重实体类表名配置 @TableName("t_order") 和数据库没有相同的名称,但名称前缀都一样,只要前面配置和依赖都没有出问题,那么运行时就不会报表不存在的错误(后续 xml 文件中实现的 sql 语句也用相同的表名)


@TableName("t_order")@Datapublic class Order {
@TableId(value = "order_id", type = IdType.ID_WORKER) private Long orderId;
private Integer userId;
}
复制代码


  1. 使用 sql 操作分表有许多禁用条件,可查看官方文档进行排查点击跳转使用规范页

测试
  1. 批量插入 20 条数据


   @Autowired    private OrderService orderService;
@Test public void insert() { List<Order> orderList =new ArrayList<Order>(); for (int i = 0; i < 20; i++) { Order orderEntity = new Order();// orderEntity.setOrderId(System.currentTimeMillis()); orderEntity.setUserId(new Random().nextInt(999)); orderList.add(orderEntity); } orderService.saveBatch(orderList); }
复制代码


  • 查看数据库,2 个表(通过分片配置算法取模)分别插入了数据


  1. 查询一条 order 数据()


    @Autowired    private OrderMapper orderMapper;        @Test    public void getOrder(){        Order orderId = orderMapper.getOrderId(1401545531558088708L);        System.out.println(orderId);    }
复制代码


<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.xf.mapper.OrderMapper">

<select id="getOrderId" resultType="com.xf.entity.Order" parameterType="long"> select * from t_order where order_id = #{id} </select>
</mapper>
复制代码


  1. 查看控制台打印的查询 sql

  2. 查询结果




完成

发布于: 刚刚阅读数: 3
用户头像

大菠萝蜜

关注

还未添加个人签名 2022.08.04 加入

还未添加个人简介

评论

发布
暂无评论
框架整合(二)- 使用Apache ShardingSphere实现数据分片_MySQL_大菠萝蜜_InfoQ写作社区