百度开源的分布式 ID 生成器,太强大了!

简介: 一、UidGenerator是什么

一、UidGenerator是什么

UidGenerator是百度开源的一款分布式高性能的唯一ID生成器,是基于snowflake模型的一种ID生成器


二、UidGenerator的优势

解决了时钟回调的问题

使用ringbuffer,无锁进行id的生产与消费,速度非常快

适用于多线程,不会有单线程瓶颈

三、整合

本次通过SpringBoot2.x和MyBatis对百度UidGenerator进行整合。


3.1 UidGenerator引入


一般使用两种方式引入UidGenerator:


1)从官网下载源码作为自己项目的一个Module引入到项目中


官网地址:https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md


2)互联网jar包引入(本文采取的是该种方式)


因为UidGenerator自带引入了mybatis,和自己项目有冲突的可以进行排除

image.png

排除冲突依赖


uid-generator中依赖了logback和mybatis。一般在项目搭建过程中,springboot中已经有了logback依赖,mybatis会作为单独的依赖引入。如果版本和uid-generator中的依赖不一致的话,就会导致冲突。


排除冲突的依赖如下:

<dependency>
    <groupId>com.xfvape.uid</groupId>
    <artifactId>uid-generator</artifactId>
    <version>0.0.4-RELEASE</version>
    <exclusions>
         <exclusion>
             <groupId>org.slf4j</groupId>
             <artifactId>log4j-over-slf4j</artifactId>
         </exclusion>
         <exclusion>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </exclusion>
          <exclusion>
             <groupId>org.mybatis</groupId>
             <artifactId>mybatis-spring</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.mybatis</groupId>
             <artifactId>mybatis</artifactId>
         </exclusion>
    </exclusions>
</dependency>

3.2 创建表

在 MySQL数据库中建一个名为 WORKER_NODE的数据表,其 sql如下:

CREATE TABLE WORKER_NODE
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name',
PORT VARCHAR(64) NOT NULL COMMENT 'port',
TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'launch date',
MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time',
CREATED TIMESTAMP NOT NULL COMMENT 'created time',
PRIMARY KEY(ID)
)
 COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;

建表时可能会报错,原因是该建表语句定义了两个TIMESTAMP字段,因为mysql 低版本控制比较严格


解决办法:


方式一:


直接把TIMESTAMP改成DATETIME 即可


方式二:


建表前先设置sql_mode:


set sql_mode="NO_ENGINE_SUBSTITUTION";

3.3 将uid-generator核心对象装配为spring的bean


uid-generator提供了两种生成器: DefaultUidGenerator、CachedUidGenerator。如对UID生成性能有要求, 请使用CachedUidGenerator。

@Configuration
public class WorkerNodeConfig {
    @Bean("disposableWorkerIdAssigner")
    public DisposableWorkerIdAssigner disposableWorkerIdAssigner(){
        DisposableWorkerIdAssigner disposableWorkerIdAssigner = new DisposableWorkerIdAssigner();
        return  disposableWorkerIdAssigner;
    }
    @Bean("cachedUidGenerator")
    public UidGenerator uidGenerator(DisposableWorkerIdAssigner disposableWorkerIdAssigner){
        CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
        cachedUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner);
        return cachedUidGenerator;
    }
}

直接创建WorkerNodeConfig类,复制以上代码。

3.4 重写WorkerIdAssigner接口

public class DisposableWorkerIdAssigner implements WorkerIdAssigner {
    @Resource
    private WorkerNodeMapper workerNodeMapper;
    @Override
    @Transactional
    public long assignWorkerId() {
        WorkerNode workerNode = buildWorkerNode();
        workerNodeMapper.addWorkerNode(workerNode);
        return workerNode.getId();
    }
    private WorkerNode buildWorkerNode() {
        WorkerNode workNode = new WorkerNode();
        if (DockerUtils.isDocker()) {
            workNode.setType(WorkerNodeType.CONTAINER.value());
            workNode.setHostName(DockerUtils.getDockerHost());
            workNode.setPort(DockerUtils.getDockerPort());
            workNode.setLaunchDate(new Date());
        } else {
            workNode.setType(WorkerNodeType.ACTUAL.value());
            workNode.setHostName(NetUtils.getLocalAddress());
            workNode.setPort(System.currentTimeMillis() + "-" + RandomUtils.nextInt(100000));
            workNode.setLaunchDate(new Date());
        }
        return workNode;
    }
}

创建一个DisposableWorkerIdAssigner类直接复制以上代码。

3.5 引入WorkerNodeMapper.xml

<?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.uidgenerator.mapper.WorkerNodeMapper">
  <resultMap id="BaseResultMap"
             type="com.uidgenerator.entity.WorkerNode">
    <id column="ID" jdbcType="BIGINT" property="id" />
    <result column="HOST_NAME" jdbcType="VARCHAR" property="hostName" />
    <result column="PORT" jdbcType="VARCHAR" property="port" />
    <result column="TYPE" jdbcType="INTEGER" property="type" />
    <result column="LAUNCH_DATE" jdbcType="DATE" property="launchDate" />
    <result column="MODIFIED" jdbcType="TIMESTAMP" property="modified" />
    <result column="CREATED" jdbcType="TIMESTAMP" property="created" />
  </resultMap>
  <insert id="addWorkerNode" useGeneratedKeys="true" keyProperty="id"
          parameterType="com.uidgenerator.entity.WorkerNode">
        INSERT INTO WORKER_NODE
        (HOST_NAME,
         PORT,
         TYPE,
         LAUNCH_DATE,
         MODIFIED,
         CREATED)
        VALUES (
          #{hostName},
          #{port},
          #{type},
          #{launchDate},
          NOW(),
          NOW())
    </insert>
  <select id="getWorkerNodeByHostPort" resultMap="BaseResultMap ">
        SELECT
            ID,
            HOST_NAME,
            PORT,
            TYPE,
            LAUNCH_DATE,
            MODIFIED,
            CREATED
        FROM
            WORKER_NODE
        WHERE
            HOST_NAME = #{host} AND PORT = #{port}
    </select>
</mapper>

可以通过mybatis生成工具直接生成文件和实体类,然后将插入和查询方法复制

注意修改resultMap中的type和insert中的keyProperty为自身项目的实体类地址

在application.yml文件中增加如下配置

image.png

image.png

3.9 访问接口测试

http://127.0.0.1:8099/test/baidu/uid

image.png

image.png

目录
相关文章
|
2月前
|
消息中间件 Kafka Apache
Apache Flink 是一个开源的分布式流处理框架
Apache Flink 是一个开源的分布式流处理框架
482 5
|
3月前
|
分布式计算 Ubuntu Hadoop
百度搜索:蓝易云【Ubuntu搭建全分布式Hadoop】
请注意,以上只是概述,并不包含详细的步骤和指令。搭建全分布式Hadoop是一个复杂的过程,需要对Hadoop的架构和配置有深入的理解,并熟悉Linux系统管理。建议在搭建全分布式Hadoop之前,先学习相关知识并查阅官方文档和教程,以确保正确搭建和配置Hadoop集群。
27 0
|
3月前
|
缓存 算法 NoSQL
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。
399 0
|
6天前
|
分布式计算 Ubuntu 调度
如何本地搭建开源分布式任务调度系统DolphinScheduler并远程访问
如何本地搭建开源分布式任务调度系统DolphinScheduler并远程访问
|
7天前
|
存储 SQL 算法
搞定了 6 种分布式ID,分库分表哪个适合做主键?
在《ShardingSphere5.x分库分表原理与实战》系列的第七篇文章中,作者探讨了分布式ID在分库分表中的重要性,以及如何利用`ShardingSphere-jdbc`的多种主键生成策略。文章介绍了`UUID`、`NanoID`、自定义雪花算法和`CosId`等策略的优缺点,并警告不要在SQL中手动拼接主键字段。此外,文章还展示了如何配置这些策略,并提醒读者`CosId`在5.2.0版本可能不可用。最后,文章讨论了如何自定义分布式主键生成算法,并强调选择策略时要考虑全局唯一性、性能和易用性。
|
27天前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
深度思考:雪花算法snowflake分布式id生成原理详解
|
1月前
|
算法 Java 数据中心
分布式ID生成系统之雪花算法详解
在当今的云计算和微服务架构盛行的时代,分布式系统已成为软件开发的重要组成部分。随着系统规模的扩大和业务的复杂化,对数据一致性和唯一性的要求也越来越高,尤其是在全局唯一标识符(ID)的生成上。因此,分布式ID生成系统应运而生,成为保证数据唯一性和提高系统可扩展性的关键技术之一。雪花算法(Snowflake)是Twitter开源的一种算法,用于生成64位的全局唯一ID,非常适用于分布式系统中生成唯一标识符。下面我们将深入探讨雪花算法的原理、结构和实现方式。
98 2
 分布式ID生成系统之雪花算法详解
|
1月前
|
NoSQL 算法 Java
【Redis】4、全局唯一 ID生成、单机(非分布式)情况下的秒杀和一人一单
【Redis】4、全局唯一 ID生成、单机(非分布式)情况下的秒杀和一人一单
65 0
|
2月前
|
存储 算法 NoSQL
全网最全的分布式ID生成方案解析
全网最全的分布式ID生成方案解析
101 0
|
3月前
|
存储 消息中间件 分布式计算
重磅开源!阿里巴巴分布式核心原理,成功登顶GitHub周榜!
分布式系统架构是当今互联网企业的重要基础设施,它能够支撑海量用户并发访问和亿级数据量的超大规模业务系统。阿里巴巴作为互联网巨头,在分布式架构方面有着丰富的经验与成果(文末有免费领取方式!)

热门文章

最新文章