ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

分布式全局ID的设计

2022-01-21 09:06:15  阅读:175  来源: 互联网

标签:tables shardingsphere ID spring sharding 全局 order id 分布式


文章目录


1. 分布式全局id概述及引发的问题

  • 在创建表的时候我们对主键id都是使用自增,通过这个来唯一区分数据
  • 在分库分表的场景中自增id就出现无法解决重复的问题了
  • 两条不同的业务数据由于id重复,就会导致查询出错或关联数据有问题

2. 通过UUID实现全局id

  • UUID通用唯一识别码
  • 缺点:只是一个单纯的id,没有实际意义,长度32位,太长没有顺序对MySQL innoDB引擎的索引组织表及不友好
  • MyCat不支持UUID的方式的,Sharding-Jdbc支持UUID的方式

2.1. 在sharding-jdbc中使用UUID进行主键数据的分库

  • 创建表
CREATE TABLE `order_content_1` (
  `id` varchar(32) NOT NULL,
  `order_amount` decimal(10,2) DEFAULT NULL,
  `order_status` int(255) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 配置properties将UUID的列作为数据库的划分方式

我们就需要将inline的规则改成standard的规则,并自己实现standard的分片规则类

# 分库的规则
spring.shardingsphere.sharding.tables.order_content.database-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.order_content.database-strategy.standard.precise-algorithm-class-name=com.icodingedu.config.MyShardingRule
# 分表的规则
spring.shardingsphere.sharding.tables.order_content.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.order_content.table-strategy.standard.precise-algorithm-class-name=com.icodingedu.config.MyShardingRule

指定id的生成规则由sharding-jdbc提供

# 指定id的生成规则为UUID,由sharding-jdbc提供
# 如果生命值的写入就会使用写入的而不是UUID
spring.shardingsphere.sharding.tables.order_content.key-generator.column=id
spring.shardingsphere.sharding.tables.order_content.key-generator.type=UUID

分库的自定义类

package com.icodingedu.config;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.Collection;

public class MyShardingRule implements PreciseShardingAlgorithm<String> {

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
        String id = preciseShardingValue.getValue();
        int mode = id.hashCode()%collection.size();
        mode = Math.abs(mode);
        Object [] nodes = collection.toArray();
        return nodes[mode].toString();
    }
}

3. 通过雪花算法实现全局id

  • SnowFlack是由Twitter提出的分布式ID算法

  • 是一个64bit的long型数字

  • 引入了时间戳的概念,保持自增

  • SnowFlack数据结构

    • 第一位是0固定不变的,表示一个正数,如果是1就是负数了
    • 41位的时间戳:当前时间减去你设置的开始时间的毫秒数,开始时间在雪花算法生成里可以设置,最长的时间范围是69年
    • 5位的机房id
    • 5位的机器id:5位机房和5位机器唯一标识机器的序列,可以配置2的10次方,也就是1024个机器在并发的情况下可以不重复
    • 12位的序号:同一时间同一机器并发可以生成2的12次方个序列,也就是说有4096个不同
    • 说明雪花支持毫秒级的并发是4096个
  • 时间回调会引起重复

    你在一开始上线的时候和实际的时间不一致,比实际早,发现后将时间修改就有一定可能导致时间重叠出现重复,重复的几率比较低

  • MyCat和sharding-jdbc都支持雪花算法

  • Sharding-jdbc可以设置最大容忍回调时间,如果超过之后再通过snowflack生成id会抛出异常

3.1. MyCat如何使用雪花生成id

# 0.首先要将id由int修改为bigint
# 1.修改server.xml的配置,修改为2将自动生成的id变更为雪花算法方式
<property name="sequnceHandlerType">2</property>
# 2.设置机房id和机器id
conf下的sequence_time_conf.properties
WORKID=03 #机器id
DATAACENTERID=03 #机房id
# 3.配置表生成的id规则
<table name="order_info" dataNode="dn213,dn214" rule="mod-long" autoIncrement="true" primaryKey="id">
		<childTable name="order_item" joinKey="order_id" parentKey="id"/>
</table>
# autoIncrement
# primaryKey

3.2. Sharding-Jdbc实现雪花

# 给两个数据源命名
spring.shardingsphere.datasource.names=ds0,ds1
# 数据源链接ds0要和命名一致
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbcUrl=jdbc:mysql://39.103.163.215:3306/shard_order
spring.shardingsphere.datasource.ds0.username=gavin
spring.shardingsphere.datasource.ds0.password=123456
# 数据源链接ds1要和命名一致
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbcUrl=jdbc:mysql://39.101.221.95:3306/shard_order
spring.shardingsphere.datasource.ds1.username=gavin
spring.shardingsphere.datasource.ds1.password=123456

# 具体的分片规则,基于数据节点
spring.shardingsphere.sharding.tables.order_info.actual-data-nodes=ds$->{0..1}.order_info_$->{1..2}
# 分库的规则
spring.shardingsphere.sharding.tables.order_info.database-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.order_info.database-strategy.inline.algorithm-expression=ds$->{id % 2}
# 分表的规则
spring.shardingsphere.sharding.tables.order_info.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.order_info.table-strategy.inline.algorithm-expression=order_info_$->{user_id % 2 + 1}
# 设定雪花id
spring.shardingsphere.sharding.tables.order_info.key-generator.column=id
spring.shardingsphere.sharding.tables.order_info.key-generator.type=snowflake
# 这里也需要设置机房id和机器id,两者合并了,是10位,所以不要超过1024
spring.shardingsphere.sharding.tables.order_info.key-generator.props.worker.id=1000
# 最大的时间容忍间隔
spring.shardingsphere.sharding.tables.order_info.key-generator.props.max.tolerate.time.difference.milliseconds=60000

标签:tables,shardingsphere,ID,spring,sharding,全局,order,id,分布式
来源: https://blog.csdn.net/tanwei010915/article/details/122613952

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有