ShardingSphere-mysql水平分片


当单表记录达到500万条或磁盘空间占用达2GB时需要考虑水平分表。水平分表是按行切分为多个表,若放在同一个服务器里能够满足性能要求就不用分库。若不能满足要求就要分库了,将表放在不同的服务器上。

一、准备服务器

根据user_id选择是哪台服务器的数据库,在根据order_id选择到具体的哪张表。

在这里插入图片描述

1.1 创建server-order0和server-order1容器

server-order0

docker run -p 3310:3306 --name server-order0 \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root  \
-d mysql:5.7

server-order1

docker run -p 3311:3306 --name server-order1 \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root  \
-d mysql:5.7

1.2 创建数据库

注意,水平分片的id需要在业务层实现,不能依赖数据库的主键。

CREATE DATABASE db_order;

CREATE TABLE t_order0(
  `id` bigint NOT NULL,
  `order_no` VARCHAR(30) NOT NULL,
  `user_id` bigint NULL DEFAULT NULL,
  `amount` decimal(10, 2) NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
);
CREATE TABLE t_order1(
  `id` bigint NOT NULL,
  `order_no` VARCHAR(30) NOT NULL,
  `user_id` bigint NULL DEFAULT NULL,
  `amount` decimal(10, 2) NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
);

1.3创建实体类

@TableName("t_order") //逻辑表名
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
    @TableId(type = IdType.ASSIGN_ID) //分布式id
    private Long id;
    private String  orderNO;
    private Long userId;
    private BigDecimal amount;
}

1.4 创建mapper

@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}

二、基本水平分片配置

2.1 基本配置

#====================基本配置
# 应用名称
spring.application.name=sharding-jdbc-demo 
#开发环境设置
spring.profiles.active=dev
# 运行模式
spring.shardingsphere.mode.type=Memory
#打印SQL
spring.shardingsphere.props.sql-show=true

2.2 数据源配置

 # 配置真实数据源
 spring.shardingsphere.datasource.names=server-order0,server-order1
 
 # 配置第 1 个数据源
 spring.shardingsphere.datasource.server-order0.type=com.zaxxer.hikari.HikariDataSource
 spring.shardingsphere.datasource.server-order0.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.shardingsphere.datasource.server-order0.jdbc-url=jdbc:mysql://mysql3:3310/db_order
 spring.shardingsphere.datasource.server-order0.username=root
 spring.shardingsphere.datasource.server-order0.password=root
 
 # 配置第 2个数据源
 spring.shardingsphere.datasource.server-order1.type=com.zaxxer.hikari.HikariDataSource
 spring.shardingsphere.datasource.server-order1.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.shardingsphere.datasource.server-order1.jdbc-url=jdbc:mysql://mysql5:33011/db_order
 spring.shardingsphere.datasource.server-order1.username=root
 spring.shardingsphere.datasource.server-order1.password=root

2.3 标准分片表配置

# =================标准分片表配置(数据节点配置)
#spring.shardingsphere.rules.sharding.tables.<table-name>.actual-data-nodes=值
# 由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式。
# 缺省表示使用已知数据源与逻辑表名称生成数据节点,用于广播表(即每个库中都需要一个同样的表用于关联查询,多为字典表)或只分库不分表且所有库的表结构完全一致的情况
#<table-name>:逻辑表名

#spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=server-order0.t_order_0,server-order0.t_order_1,server-order1.t_order_0,server-order1.t_order_1
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=server-order$->{0..1}.t_order$->{0..1}

行表达式:https://shardingsphere.apache.org/document/5.1.1/cn/features/sharding/concept/inline-expression/

2.4 分片算法配置

水平分库

分片算法

#=================水平分库
# 分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一
# 用于单分片键的标准分片场景
# 分片列名称
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=my_inline_user_id

# =================分片算法配置
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.my_inline_user_id.type=INLINE
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.my_inline_user_id.props.algorithm-expression=server-order$->{user_id % 2}

水平分表

# 分表策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_no
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=alg_hash_mod

# =================分片算法配置
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_hash_mod.type=HASH_MOD
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_hash_mod.props.sharding-count=2

2.5 测试

@SpringBootTest
public class ShardTest {

    @Autowired
    private OrderMapper orderMapper;



    /**
     * 水平分片:分表插入数据测试
     */
    @Test
    public  void testInsertOrderTableStrategy(){

        for (long i = 1; i <5 ; i++) {
            Order order=new Order();
            order.setOrderNo("ATGUIGU"+i);//分表键
            order.setUserId(1l);//分库键
            order.setAmount(new BigDecimal(100));
            orderMapper.insert(order);
        }
        for (long i = 5; i <9 ; i++) {
            Order order=new Order();
            order.setOrderNo("ATGUIGU"+i);//分表键
            order.setUserId(2l);//分库键
            order.setAmount(new BigDecimal(100));
            orderMapper.insert(order);
        }
    }

    /**
     * 水平分片:查询所有记录
     */
    @Test
    public  void testShardSelectAll(){

        List<Order> orderList = orderMapper.selectList(null);
        orderList.forEach(System.out::println);
    }

    /**
     * 水平分片:根据user_id查询记录
     */
    @Test
    public  void testShardSelectByUserId(){
        QueryWrapper<Order> orderQueryWrapper=new QueryWrapper<>();
        orderQueryWrapper.eq("user_id",1L);
        List<Order> orderList = orderMapper.selectList(orderQueryWrapper);
        orderList.forEach(System.out::println);
    }

三、分布式主键

分布式主键

水平分片需要关注全局序列,因为不能简单的使用基于数据库的主键自增。

这里有两种方案,一种是基于MyBatisPlus的id策略,一种是ShardingSphere-jdbc的全局序列配置。

  • 基于MyBatisPlus的id策略:将Order类的id设置成如下形式
@TableId(type = IdType.ASSIGN_ID) //分布式id
    private Long id;
  • 基于ShardingSphere-jdbc的全局序列配置:和前面的MyBatisPlus的策略二选一
  //当配置了ShardingSphere-jdbc的分布式序列时,自动使用ShardingSphere-jdbc的分布式序列
    //当没有配置了ShardingSphere-jdbc的分布式序列时,自动依赖数据库的自增策略
    @TableId(type = IdType.AUTO)
    //@TableId(type = IdType.ASSIGN_ID) //分布式id(默认值)
    private Long id;
# 分布式序列策略配置
# 分布式序列列名称
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=id
# 分布式序列算法名称
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=alg_snowflake


# 分布式序列算法配置
# 分布式序列算法类型
spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.type=SNOWFLAKE
# 分布式序列算法属性配置
#spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.props.xxx=

数据分片
分布式序列算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值