首页 > 其他分享 >Sharding自定义分片策略

Sharding自定义分片策略

时间:2023-08-10 13:33:16浏览次数:41  
标签:自定义 userId id ShardingSliceAutoFillProperties 分片 Sharding import public logEnabl

公司分库分表使用用户id,主键后3位拼接用户id后三位,现把相关分片规则自定义简易组件使用

一、参数配置

引用者可以配置主键字段与用户字段命名,配置分片日志记录等

package com.ypshengxian.shardingslice.properties;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 描述:自动填充配置
 * Created by zjw on 2022/3/18 09:58
 */
@ConfigurationProperties(prefix = "ypsx.sharding-slice.auto-fill")
public class ShardingSliceAutoFillProperties {
    /**
     * 是否开启日志记录
     */
    public static boolean logEnabled = true;
    /**
     * 主键字段名, 数据库字段, 默认为id
     */
    public static String id = "id";
    /**
     * 用户字段名, 数据库字段, 默认为user_id
     */
    public static String userId = "user_id";
    /**
     * 库表是否以0开始
     * 例如:order_0, order_1
     * 反例:order_1, order_2
     */
    public static boolean isZeroStart = true;

    @Value("${logEnabled:true}")
    public void setLogEnabled(boolean logEnabled) {
        this.logEnabled = logEnabled;
    }

    @Value("${id:id}")
    public void setId(String id) {
        this.id = id;
    }

    @Value("${userId:user_id}")
    public void setUserId(String userId) {
        this.userId = userId;
    }

    @Value("${isZeroStart:true}")
    public void setIsZeroStart(boolean isZeroStart) {
        this.isZeroStart = isZeroStart;
    }

    public static String propertiesToString(){
        return "CartDO{" +
                "id=" + id +
                ", userId=" + userId +
                ", logEnabled=" + logEnabled +
                ", isZeroStart=" + isZeroStart +'\'' +
                '}';
    }
}

二、分片算法

需要实现ComplexKeysShardingAlgorithm接口

package com.ypshengxian.shardingslice.config;

import com.ypshengxian.shardingslice.properties.ShardingSliceAutoFillProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述:sharding 分片策略(库表通用)
 * Created by zjw on 2022/3/16 12:42
 */
@Slf4j
public class ShardingSliceComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {


    public ShardingSliceComplexKeysShardingAlgorithm() {}

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<Long> shardingValue) {
        if (ShardingSliceAutoFillProperties.logEnabled) {
            log.info("ShardingSliceAutoFillProperties:{}", ShardingSliceAutoFillProperties.propertiesToString());
        }
        if (!shardingValue.getColumnNameAndRangeValuesMap().isEmpty()) {
            return new HashSet<>(availableTargetNames);
        }
        if (ShardingSliceAutoFillProperties.logEnabled) {
            log.info("所有ShardingSliceComplexKeysShardingAlgorithm:{}", shardingValue.getColumnNameAndShardingValuesMap());
        }
        // 获取id
        Collection<Long> cartIds = shardingValue.getColumnNameAndShardingValuesMap().getOrDefault(ShardingSliceAutoFillProperties.id, new ArrayList<>(1));
        // 获取用户id
        Collection<Long> customerIds = shardingValue.getColumnNameAndShardingValuesMap().getOrDefault(ShardingSliceAutoFillProperties.userId, new ArrayList<>(1));

        // 整合id和用户id
        List<Long> ids = new ArrayList<>(16);
        ids.addAll(cartIds);
        ids.addAll(customerIds);

        List<String> shardingAlgorithm = ids.stream()
                // 对可用的表名求余数,获取到真实的表的后缀
                .map(idSuffix -> {
                    long suffix = idSuffix % 1000 % availableTargetNames.size();
                    return (ShardingSliceAutoFillProperties.isZeroStart) ? suffix : suffix + 1;
                })
                // 去重
                .distinct()
                // 转换成string
                .map(String::valueOf)
                // 获取到真实的表
                .map(tableSuffix -> availableTargetNames.stream().filter(targetName -> targetName.endsWith(tableSuffix)).findFirst().orElse(null))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (ShardingSliceAutoFillProperties.logEnabled) {
            log.info("sharding slice result:{}", shardingAlgorithm);
        }

        return shardingAlgorithm;
    }

}

三、spring.factories启动扫描

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ypshengxian.shardingslice.config.ShardingSliceAutoConfigure

四、使用配置

spring:
  profiles:
    active: dev
  shardingsphere:
    props:
      sql.show: true # 线上环境需要关闭
    datasource:
      names: ds0
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/yipin_cart?serverTimezone=Asia/Shanghai&autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
        username: root
        password: 123456
        maxActive: 100
        maxWait: 1000
    sharding:
      default-data-source-name: ds0
      tables:
        cart:
          actual-data-nodes: ds0.cart_$->{0..7}
          database-strategy:
            complex:
              sharding-columns: user_id
              algorithm-class-name: com.ypshengxian.shardingslice.config.ShardingSliceComplexKeysShardingAlgorithm
          table-strategy:
            complex:
              sharding-columns: id,user_id
              algorithm-class-name: com.ypshengxian.shardingslice.config.ShardingSliceComplexKeysShardingAlgorithm

标签:自定义,userId,id,ShardingSliceAutoFillProperties,分片,Sharding,import,public,logEnabl
From: https://blog.51cto.com/u_11906056/7033369

相关文章

  • 利用pytorch自定义CNN网络(三):构建CNN模型
    本文是利用pytorch自定义CNN网络系列的第三篇,主要介绍如何构建一个CNN网络,关于本系列的全文见这里。笔者的运行设备与软件:CPU(AMDRyzen™54600U)+pytorch(1.13,CPU版)+jupyter;本文所用到的资源:链接:https://pan.baidu.com/s/1WgW3IK40Xf_Zci7D_BVLRg提取码:12121.如何......
  • Vue 自定义组件
    下面有一个例子。<template><el-input:value="value"@click.native="select"readonly><iclass="el-icon-circle-close"slot="suffix"@[email protected]="clear"/>&l......
  • 七月学习之Iptables自定义链
    9、Iptables自定义链9.1、为什么要使用自定义链iptables的默认链就已经能够满足我们了,为什么还需要自定义链呢当默认链中的规则非常多时,不便于管理1、假设INPUT链中存放了100条规则,这100条规则有针对80端口的,有针对22端口的2、如果想修改22端口的规则,则需要将所有规则都看一遍,......
  • 利用pytorch自定义CNN网络(二):数据集的准备
    本文是利用pytorch自定义CNN网络系列的第二篇,主要介绍构建网络前数据集的准备,关于本系列的全文见这里。笔者的运行设备与软件:CPU(AMDRyzen™54600U)+pytorch(1.13,CPU版)+jupyter;本文所用到的资源:链接:https://pan.baidu.com/s/1WgW3IK40Xf_Zci7D_BVLRg提取码:1212在训......
  • camera2 传参流程以及hal添加自定义参数方法
    camera2传参流程以及hal添加自定义参数方法//设置自动曝光模式mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);/frameworks/base/core/java/android/hardware/camera2/CaptureRequest.javaKey<Integer>CONTROL_AF_MOD......
  • excel wps宏编辑器,用JavaScript自定义函数设置单元格符合条件后,那一行都变色
        functionjudge(){varapp=Application;//WPS表格的应用程序对象varwb=app.ActiveWorkbook;//当前工作簿varsheet=wb.ActiveSheet;//当前工作表vardataRange=sheet.UsedRange;//使用的数据范围varnumRows=dataRange.Rows......
  • django自定义过滤器
    https://docs.djangoproject.com/zh-hans/3.1/howto/custom-template-tags/代码布局自定义的tags和filters会保存在模块名为 templatetags 的目录内。模块文件的名字即稍候你用来加载tags的名字,所以小心不要采用一个可能与其它应用自定义的tags和filters冲突的名......
  • java笔记_12_自定义注解
    1、@interface用于声明注解,参数只用八种基本数据类型和四种数据类型(基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String,Enum,Class,annotations),如果只有一个参数成员,最好把参数名称设为"value"2、@Target说明了Annotation所修饰的对象范围,......
  • 利用pytorch自定义CNN网络(一):torchvision工具箱
    本文是利用pytorch自定义CNN网络系列的第一篇,主要介绍torchvision工具箱及其使用,关于本系列的全文见这里。笔者的运行设备与软件:CPU(AMDRyzen™54600U)+pytorch(1.13,CPU版)+jupyter;本文所用到的资源:链接:https://pan.baidu.com/s/1WgW3IK40Xf_Zci7D_BVLRg提取码:1212......
  • 切面实现下单请求防重提交功能(自定义注释@repeatSubmit)
    该切面功能适用场景下单请求多次提交,导致生成多个相同的订单解决方案前端解决:限制点击下单按钮为1次后失效。不足:用户体验下降,能绕过前端后端解决:防重提交切面解决,自定义注释实现该功能(如下)步骤:自定义注释类RepeatSubmit创建切面并有该注释绑定,在切面类实现防重提......