分布式系统的唯一id如何生成(代码片段)

小志的博客 小志的博客     2023-02-25     504

关键词:

一、雪花算法的提前

  • 针对业务数据来说,通常都是需要唯一id的,比如学生的学号、订单的订单号,支付流水的流水号等等。

  • 采用最简单的方式,就是插入时候设置主键auto increment的自增方式。那么插入表中的数据都是唯一的,不过方案虽然简单,但是弊端确实很多。
    (1)、比如通过这种自增的方式,用户很容易就会通过遍历id的方式,获得库中的业务数据,并且如果采用了分库分表的方式,那么就无法通过主键自增的方式来控制业务数据唯一性。

  • 如果采取MD5的方式呢,却失去了业务含义,并且不利于在分库分表的场景下,通过id快速确定数据在哪个库或哪张表上。

  • 针对这种情况,我们可以采用雪花算法来解决。

二、雪花算法的概述

  • 雪花算法(snowflake)是Twitter开源的分布式ID生成算法,它会返回一个long类型的唯一ID。
  • 这种方案大致来说是一种以划分命名空间来生成ID的一种算法,这种方案把32或64-bit分别划分成多段,分开来标示机器、时间等。



三、雪花算法的代码实现

1、雪花算法代码

package com.xz.springboottest.day6;

/**
 * @description: snowflake算法
 * @author: xz
 */
public class SnowFlake 
    /**
     * 起始的时间戳
     */
    private final static long START_STAMP = 1480166465631L;

    /**
     * 每一部分占用的位数
     */
    private final static long SEQUENCE_BIT = 12; //序列号占用的位数
    private final static long MACHINE_BIT = 5;   //机器标识占用的位数
    private final static long DATA_CENTER_BIT = 5;//数据中心占用的位数

    /**
     * 每一部分的最大值
     */
    private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); //序列号最大值
    private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);//机器标识最大值
    private final static long MAX_DATA_CENTER_NUM = -1L ^ (-1L << DATA_CENTER_BIT);//数据中心最大值

    /**
     * 每一部分向左的位移
     */
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long DATA_CENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private final static long TIMESTAMP_LEFT = DATA_CENTER_LEFT + DATA_CENTER_BIT;


    /**
     * 定义参数
     * */
    private long dataCenterId;  //数据中心
    private long machineId;     //机器标识
    private long sequence = 0L; //序列号
    private long lastStamp = -1L;//上一次时间戳

    /**
     * 带参数的构造函数
     * */
    public SnowFlake(long dataCenterId, long machineId) 
        if (dataCenterId > MAX_DATA_CENTER_NUM || dataCenterId < 0) 
            throw new IllegalArgumentException("dataCenterId can't be greater than MAX_DATA_CENTER_NUM or less than 0");
        
        if (machineId > MAX_MACHINE_NUM || machineId < 0) 
            throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
        
        this.dataCenterId = dataCenterId;
        this.machineId = machineId;
    


    /**
     * 产生下一个ID
     *
     * @return
     */
    public synchronized long nextId() 
        long currStamp = getNewStamp();
        if (currStamp < lastStamp) 
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        

        if (currStamp == lastStamp) 
            //相同毫秒内,序列号自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            //同一毫秒的序列数已经达到最大
            if (sequence == 0L) 
                currStamp = getNextMill();
            
         else 
            //不同毫秒内,序列号置为0
            sequence = 0L;
        

        lastStamp = currStamp;

        return (currStamp - START_STAMP) << TIMESTAMP_LEFT //时间戳部分
                | dataCenterId << DATA_CENTER_LEFT       //数据中心部分
                | machineId << MACHINE_LEFT             //机器标识部分
                | sequence;                             //序列号部分
    

    private long getNextMill() 
        long mill = getNewStamp();
        while (mill <= lastStamp) 
            mill = getNewStamp();
        
        return mill;
    

    private long getNewStamp() 
        return System.currentTimeMillis();
    



2、测试代码


分布式id生成策略(代码片段)

分布式系统唯一ID生成方案汇总系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。生成ID的方法有很多,适应不同的场景、需求以及性能要求。所以有些比较复杂的系统会有多个ID生成的策略... 查看详情

分布式系统唯一id生成方案汇总(代码片段)

分布式系统唯一ID生成方案汇总系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。生成ID的方法有很多,适应不同的场景、需求以及性能要求。所以有些比较复杂的系统会有多个ID生成的策略... 查看详情

分布式系统的唯一id如何生成(代码片段)

...花算法的概述雪花算法(snowflake)是Twitter开源的分布式ID生成算法,它会返回一个long类型的唯一ID。这种方案大致来说是一种以划分命名空间来生成ID的一种算法,这种方案把32或64-bit分别划分成多段,分开来... 查看详情

分布式系统的唯一id如何生成(代码片段)

...花算法的概述雪花算法(snowflake)是Twitter开源的分布式ID生成算法,它会返回一个long类型的唯一ID。这种方案大致来说是一种以划分命名空间来生成ID的一种算法,这种方案把32或64-bit分别划分成多段,分开来... 查看详情

分布式系统唯一id的生成方案讨论(代码片段)

在分布式系统下唯一id问题,就是id咋生成?比如分表分库,因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那是不对的。举个例子,一个表拆分为了2张表,每个表的id都从1开始累加,这个肯定有问题了!... 查看详情

分布式系统id生成方案汇总(代码片段)

在分布式系统中,需要对大量的数据、消息、请求等进行唯一的标识,例如分布式数据库的ID需要满足唯一且多数据库同步,在单一系统中,使用数据库自增主键可以满足需求,但是在分布式系统中就需要一个能够生成全局唯一I... 查看详情

雪花算法:分布式唯一id生成利器(代码片段)

前言无论是在分布式系统中的ID生成,还是在业务系统中请求流水号这一类唯一编号的生成,都是软件开发人员经常会面临的一场景。而雪花算法便是这些场景的一个解决方案。以分布式ID为例,它的生成往往会在唯... 查看详情

详解分布式系统中的唯一id生成策略(代码片段)

...4.redis生成5. Twitter的snowflake算法snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着... 查看详情

图解各路分布式id生成算法(代码片段)

在分布式系统中,通常会用到分布式ID来标注数据的唯一性,而分布式ID的生成方式又多种多样,今天我们就来讨论一下主流的分布式ID生成策略。分布式ID基本需求全局唯一趋势递增信息安全全局唯一这是基本要求,不必解释趋... 查看详情

一线大厂的分布式唯一id生成方案是什么样的?(代码片段)

...Java、Redis、MongoDB、MySQL、Zookeeper、SpringCloud、Dubbo高并发分布式等教程,一共30G,需要自己领取。传送门:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ一、前言分布式系统中我们会对一些数据量大的业务进行分拆,如:用户表,订单表... 查看详情

分布式系统唯一id生成方案汇总(代码片段)

目录1.数据库自增长序列或字段2.UUID3.UUID的变种4.Redis生成ID5.Twitter的snowflake算法6.利用zookeeper生成唯一ID7.MongoDB的ObjectId8.TiDB的主键系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。生成ID... 查看详情

分布式id生成系统(代码片段)

...#xff0c;美团点评基础架构团队成员,主要参与美团大型分布式链路跟踪系统Mtrace和美团点评分布式ID生成系统Leaf的开发工作。背景驱动在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。如在美团点评的金... 查看详情

架构设计|分布式业务系统中,全局id生成策略(代码片段)

...,仅供参考。二、雪花算法1、概念简介Twitter公司开源的分布式ID生成算法策略,生成的ID遵循时间的顺序。1为位标识,始终为0,不可用;41位时间截,存储时间截的差值(当前时间截-开始时间截);10位的机器标识,10位的长度... 查看详情

架构设计|分布式业务系统中,全局id生成策略(代码片段)

...,仅供参考。二、雪花算法1、概念简介Twitter公司开源的分布式ID生成算法策略,生成的ID遵循时间的顺序。1为位标识,始终为0,不可用;41位时间截,存储时间截的差值(当前时间截-开始时间截);10位的机器标识,10位的长度... 查看详情

在分布式场景,生成唯一id(代码片段)

在分布式环境下生成数据库主键是一件比较麻烦的事情,这里简单总结下,以供以后使用。数据库自增长序列或字段每个服务器使用自增主键,不同服务器的步长不一样,比如A服务器生成1,3,5,7...B服务器生成2,4,6,8...。... 查看详情

分布式id解决方案之美团leaf(代码片段)

分布式ID在庞大复杂的分布式系统中,通常需要对海量数据进行唯一标识,随着数据日渐增长,对数据分库分表以后需要有一个唯一ID来标识一条数据,而数据库的自增ID显然不能满足需求,此时就需要有一个能够生成全局唯一ID... 查看详情

分布式服务自增长唯一id小结(代码片段)

1、常用生成唯一ID的方式,例如UUID 2、生成唯一自自增长ID方式:  例如:Zookeeper的增加ID;redis的incr方法mongodb的objectId3、采用雪花模型如下代码:1/**2*采用twitter的雪花算法,生成有一定顺序且不重复的id,结果类型为64位... 查看详情

分布式id生成方案-snowflake算法(代码片段)

...各种各样的ID,这些ID需要保证全局唯一。我们称之为分布式ID,分布式ID需要满足唯一性、趋势递增性、高可用性、高性能等特点。snowflake算法,也叫雪花算法,是其中的一种分布式ID生成方案。是twitter公司内部... 查看详情