SnowFlake算法Java实现(雪花算法)生成分布式ID

Java-雪花算法(snowflak)生成有序不重复ID的Java实现 使用了按位左移操作,最终将时间戳差值、机器码、顺序号,三个值合并到一个long中。这个算法有个好处是,可以把ID解码,得到时间、机器码和顺序号。/** 长度64位,其中:* 1位符号位,0正数,1负数* 41位毫秒级时间戳,41111111111111111111111111111* 10位机器ID,11 1111 1111* 12位序列号,1111 1111 1111* */在后端系统中,使用64位long类型的ID通常不会遇到问题。 阅读详情

【订阅专栏合集,关注公众号,作者所有付费文章都能看(持续更新)】

SnowFlake 算法是 Twitter 开源的分布式唯一 ID 生成算法,其具有高性能、低延迟、按时间趋势有序等特点。理论支持每毫秒生成 4096 个不同数字,能够满足绝大多数高并发场景下的互联网应用。

本文会讲到如下内容:

  • SnowFlake 的基本概念
  • 基于内存的 WorkerId、DatacenterId 自动生成
  • 单位毫秒内的ID初始值随机生成
  • 运行时、系统重启时 时钟回拨处理
  • 十进制数字字符串位数补齐
  • SnowFlake 完整实现:Java 版
  • 业务定制雪花算法案例:订单号生成

适合人群: 需要在实际应用中生成分布式唯一 ID 的技术人员,Java 程序员

gitchat地址: https://gitbook.cn/gitchat/activity/5f43c3e4f9fe2a086081397e

详细代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 基于SnowFlake的Id生成器使用方法见下方的main方法中的测试demo
 * 可以自行传入workerId和datacenterId;也可以直接使用默认的构造器创建,开箱即用,简单方便
 */
public class IdGenerator {

    private static final Logger logger = LoggerFactory.getLogger(IdGenerator.class);

    //工作机器id
    private long workerId;
    //数据中心id
    private long datacenterId;
    //序列号
    private long sequence = 0L;

    //基准时间,一般取系统的最近时间(一旦确定不能变动)
    private long twepoch;

    private long workerIdBits;
    private long datacenterIdBits;
    private long maxWorkerId;
    private long maxDatacenterId;

    //毫秒内自增位数
    private long sequenceBits;
    //位与运算保证毫秒内Id范围
    private long sequenceMask;

    //工作机器id需要左移的位数
    private long workerIdShift;
    //数据中心id需要左移位数
    private long datacenterIdShift;
    //时间戳需要左移位数
    private long timestampLeftShift;

    //上次生成id的时间戳,初始值为负数
    private long lastTimestamp = -1L;

    //true表示毫秒内初始序列采用随机值
    private boolean randomSequence;
    //随机初始序列计数器
    private long count = 0L;

    //允许时钟回拨的毫秒数
    private long timeOffset;

    private final ThreadLocalRandom tlr = ThreadLocalRandom.current();

    /**
     * 无参构造器,自动生成workerId/datacenterId,开箱即用
     */
    public IdGenerator() {
        this(false, 10, null, 5L, 5L, 12L);
    }

    /**
     * 有参构造器,调用者自行保证数据中心ID+机器ID的唯一性
     * 标准snowflake实现
     *
     * @param workerId     工作机器 ID
     * @param datacenterId 数据中心ID
     */
    public IdGenerator(long workerId, long datacenterId) {
        this(workerId, datacenterId, false, 10, null, 5L, 5L, 12L);
    }

    /**
     * @param randomSequence   true表示每毫秒内起始序号使用随机值
     * @param timeOffset       允许时间回拨的毫秒数
     * @param epochDate        基准时间
     * @param workerIdBits     workerId位数
     * @param datacenterIdBits datacenterId位数
     * @param sequenceBits     sequence位数
     */
    public IdGenerator(boolean randomSequence, long timeOffset, Date epochDate, long workerIdBits, long datacenterIdBits, long sequenceBits) {
        if (null != epochDate) {
            this.twepoch = epochDate.getTime();
        } else {
            // 2012/12/12 23:59:59 GMT
            this.twepoch = 1355327999000L;
        }

        this.workerIdBits = workerIdBits;
        this.datacenterIdBits = datacenterIdBits;
        this.maxWorkerId = -1L ^ (-1L << workerIdBits);
        this.maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

        this.sequenceBits = sequenceBits;
        this.sequenceMask = -1L ^ (-1L << sequenceBits);

        this.workerIdShift = sequenceBits;
        this.datacenterIdShift = sequenceBits + workerIdBits;
        this.timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

        this.datacenterId = getDatacenterId(maxDatacenterId);
        this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
        this.randomSequence = randomSequence;
        this.timeOffset = timeOffset;
        String initialInfo = String.format("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, datacenterid  %d, workerid %d",
                timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, datacenterId, workerId);
        logger.info(initialInfo);
    }

    /**
     * 自定义workerId+datacenterId+其它初始配置
     * 调整workerId、datacenterId、sequence位数定制雪花算法,控制生成的Id的位数
     *
     * @param workerId         工作机器 ID
     * @param datacenterId     数据中心ID
     * @param randomSequence   true表示每毫秒内起始序号使用随机值
     * @param timeOffset       允许时间回拨的毫秒数
     * @param epochDate        基准时间
     * @param workerIdBits     workerId位数
     * @param datacenterIdBits datacenterId位数
     * @param sequenceBits     sequence位数
     */
    public IdGenerator(long workerId, long datacenterId, boolean randomSequence, long timeOffset, Date epochDate, long workerIdBits, long datacenterIdBits, long sequenceBits) {
        this.workerIdBits = workerIdBits;
        this.datacenterIdBits = datacenterIdBits;
        this.maxWorkerId = -1L ^ (-1L << workerIdBits);
        this.maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0\r\n", maxWorkerId));
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0\r\n", maxDatacenterId));
        }

        if (null != epochDate) {
            this.twepoch = epochDate.getTime();
        } else {
            // 2012/12/12 23:59:59 GMT
            this.twepoch = 1355327999000L;
        }

        this.sequenceBits = sequenceBits;
        this.sequenceMask = -1L ^ (-1L << sequenceBits);

        this.workerIdShift = sequenceBits;
        this.datacenterIdShift = sequenceBits + workerIdBits;
        this.timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

        this.workerId = workerId;
        this.datacenterId = datacenterId;
        this.timeOffset = timeOffset;
        this.randomSequence = randomSequence;

        String initialInfo = String.format("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, datacenterid  %d, workerid %d",
                timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, datacenterId, workerId);
        logger.info(initialInfo);
    }

    private static long getDatacenterId(long maxDatacenterId) {
        long id = 0L;
        try {
            InetAddress ip = InetAddress.getLocalHost();
            NetworkInterface network = NetworkInterface.getByInetAddress(ip);
            if (network == null) {
                id = 1L;
            } else {
                byte[] mac = network.getHardwareAddress();
                if (null != mac) {
                    id = ((0x000000FF & (long) mac[mac.length - 1]) | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
                    id = id % (maxDatacenterId + 1);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("GetDatacenterId Exception", e);
        }
        return id;
    }

    private static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
        StringBuilder macIpPid = new StringBuilder();
        macIpPid.append(datacenterId);
        try {
            String name = ManagementFactory.getRuntimeMXBean().getName();
            if (name != null && !name.isEmpty()) {
                //GET jvmPid
                macIpPid.append(name.split("@")[0]);
            }
            //GET hostIpAddress
            String hostIp = InetAddress.getLocalHost().getHostAddress();
            String ipStr = hostIp.replaceAll("\\.", "");
            macIpPid.append(ipStr);
        } catch (Exception e) {
            throw new RuntimeException("GetMaxWorkerId Exception", e);
        }
        //MAC + PID + IP的 hashcode 取低16位
        return (macIpPid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
    }

    public synchronized long nextId() {
        long currentTimestamp = timeGen();

        //获取当前时间戳如果小于上次时间戳,则表示时间戳获取出现异常
        if (currentTimestamp < lastTimestamp) {
            // 校验时间偏移回拨量
            long offset = lastTimestamp - currentTimestamp;
            if (offset > timeOffset) {
                throw new RuntimeException("Clock moved backwards, refusing to generate id for [" + offset + "ms]");
            }

            try {
                // 时间回退timeOffset毫秒内,则允许等待2倍的偏移量后重新获取,解决小范围的时间回拨问题
                this.wait(offset << 1);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            currentTimestamp = timeGen();
            if (currentTimestamp < lastTimestamp) {
                throw new RuntimeException("Clock moved backwards, refusing to generate id for [" + offset + "ms]");
            }
        }

        //如果获取的当前时间戳等于上次时间戳(即同一毫秒内),则序列号自增
        if (lastTimestamp == currentTimestamp) {
            // randomSequence为true表示随机生成允许范围内的起始序列,否则毫秒内起始值从0L开始自增
            long tempSequence = sequence + 1;
            if (randomSequence) {
                sequence = tempSequence & sequenceMask;
                count = (count + 1) & sequenceMask;
                if (count == 0) {
                    currentTimestamp = this.tillNextMillis(lastTimestamp);
                }
            } else {
                sequence = tempSequence & sequenceMask;
                if (sequence == 0) {
                    currentTimestamp = this.tillNextMillis(lastTimestamp);
                }
            }
        } else {
            sequence = randomSequence ? tlr.nextLong(sequenceMask + 1) : 0L;
            count = 0L;
        }

        lastTimestamp = currentTimestamp;

        return ((currentTimestamp - twepoch) << timestampLeftShift) |
                (datacenterId << datacenterIdShift) |
                (workerId << workerIdShift) |
                sequence;
    }

    private long tillNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    private long timeGen() {
        return System.currentTimeMillis();
    }

//测试
    public static void main(String[] args) {
//        for (int i = 0; i < 10; i++) {
//            IdGenerator idGenerator = new IdGenerator();//使用默认构造器创建,开箱即用
//            new Thread(() -> {
//                for (int j = 0; j < 100; j++) {
//                    System.out.println(idGenerator.nextId());
//                }
//            }).start();
//        }

//        IdGenerator idGenerator = new IdGenerator(1, 1);
//        for (int j = 0; j < 2000; j++) {
//            System.out.println(System.currentTimeMillis() + " " + idGenerator.nextId());
//        }

//        IdGenerator idGenerator = new IdGenerator(true, 10, null, 3L, 2L, 7L);
//        for (int j = 0; j < 2000; j++) {
//            System.out.println(System.currentTimeMillis() + " " + idGenerator.nextId());
//        }

        IdGenerator shortIdGenerator = new IdGenerator(7, 3, true, 10, null, 3, 2, 7);
        for (int j = 0; j < 1000; j++) {
            System.out.println(System.currentTimeMillis() + " " + shortIdGenerator.nextId());
        }
    }
}

如有问题请留言~

【SnowFlake】雪花算法(Java版本) SnowFlake雪花算法(Java版本) 阅读详情

相关推荐

雪花算法SnowFlake 细致易懂 Java/Springboot实现

细致讲解雪花算法,一看就懂!!!

prjh_的博客 1万+

ID生成方式Java——雪花算法

12 bit 可以代表的最大正整数是 2 ^ 12 - 1 = 4095,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的 4096 个不同的 id。但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。这 64个bit中,其中1个bit是不用的,然后用其中的41bit作为毫秒数,用10bit 作为工作机器 id,12bit作为序列号。因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。.

qq_42900213的博客 1万+

雪花算法(Snowflake),生成主键ID

IdUtil类 public class IdUtil { // 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动) private final static long twepoch = 1288834974657L; // 机器标识位数 private final static long workerIdBits = 5L; // 数据中心标识位数 private final static long dataCenterIdBits =

qq_41153405的博客 1624

java中使用雪花算法(Snowflake)为分布式系统生成全局唯一ID

使用雪花算法(Snowflake)为分布式系统中生成全局唯一ID,使用java语言实现

github_38727595的博客 6633

电商平台面试必问算法之雪花算法(SnowFlake)

这篇文章只是做一个简介和了解。 如果不是电商平台的程序猿和程序媛们,可以看个热闹。 电商平台的胖友们可以踊跃发言,给点真诚的建议,万分感谢~ 分布式ID算法面对的场景 在分布式系统中,肯定需要对大量的数据和消息进行唯一标识,最简单的比如订单号。 像京东或者淘宝在双十一或者 618 的时候,短时间内订单肯定会指数性暴增。那么如何提供有效和唯一的ID进行订单的标识,这时候就需要用到分布式ID算法了。 解决方案 数据库自增ID: 在不多的数据量下也可以实现,但是大数...

pontuss的博客 1079

Verilog仿真必备:FSDB dump命令全解析与实战配置指南

本文深入解析了Verilog仿真中FSDB波形记录的核心命令与实战配置技巧。针对大规模SoC验证场景,详细介绍了如何通过$fsdbDumpvars、$fsdbDumpfile等命令实现信号精准捕获、文件体积控制和动态启停,并提供了智能化的分层dump策略,帮助工程师在保证调试信息完整性的同时,大幅提升验证效率并有效管理波形数据。

cnn8visionary的博客 349

订单号 雪花算法java,分布式id生成-雪花算法(SnowFlake)实现

分布式id生成-雪花算法(SnowFlake)实现分布式id生成-雪花算法(SnowFlake)实现1 雪花算法原理SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图:1bit,不用,二进制中最高位是符号位,0表示正数,固定是041bit,毫秒时间戳,2^41-1毫秒时间戳表示可使用69年10bit,工作机器id,前5位表示机房id,后5位表示机器id,最大支持2^5 ...

weixin_30461129的博客 732

3GPP协议解读_物理层系列(一)_物理层协议怎么看?

5G NR相关协议一般都在38系列,点进去以后可以看到,38.2xx系列为物理层相关协议,为了掌握物理层相关知识,应该怎么看协议呢?我建议从38.201读起,对38.2xx系列协议有一个整体的把握。

JCMLSY的博客 1329

分布式 ID 生成方案:雪花算法(Snowflake)的原理与 Java 实现

雪花算法通过时间有序性、节点隔离和序列化机制,实现了分布式环境下的高效ID生成。$O(1)$ 时间复杂度生成ID无需中心化协调服务生成ID具备时间可解析性实际应用中需根据业务场景调整时间精度和节点分配策略,并建立完善的时钟同步监控机制。

idhsajkhs的博客 464

鱼眼相机矫正实战:除了棋盘格,试试横向展开和经纬度法(OpenCV4/C++实现对比)

本文对比了鱼眼相机矫正的三种主流方法:棋盘格标定法、横向展开法和经纬度法,通过OpenCV4/C++实战代码解析,帮助开发者在自动驾驶、VR全景拼接和安防监控等场景中选择最适合的技术方案。重点分析了各方法的精度、处理速度和适用场景,为工程实践提供实用指导。

weixin_29032489的博客 284

Lede(OpenWrt)安装和双宽带叠加

LEDE是一个专为路由器和嵌入式设备设计的自由和开源的操作系统。LEDE是OpenWRT项目的一个分支项目。LEDE操作系统包括许多路由器有用的功能,如网络地址转换、防火墙、端口转发、DHCP服务器等。

我的博客 6441

雪花算法原理_Snowflake 雪花算法

分布式系统中ID生成方案,比较简单的是UUID(Universally Unique Identifier,通用唯一识别码),但是其存在两个明显的弊端:一、UUID是128位的,长度过长;二、UUID是完全随机的,无法生成递增有序的UUID。而现在流行的基于 Snowflake 雪花算法的ID生成方案就可以很好的解决了UUID存在的这两个问题原理Snowflake 雪花算法,由Twitt...

weixin_39805409的博客 404

从分立到集成:深入解析Buck电路的核心模块与设计权衡

本文深入解析Buck电路的核心模块与设计权衡,从分立到集成方案的优缺点对比。详细探讨Buck电路的高效能量转换、小型化设计及灵活电压调节能力,并结合实际案例分享分立方案中的PWM生成、反馈环路设计及保护电路优化经验,为工程师提供实用设计参考。

weixin_29306317的博客 223

雪花算法(snowflake)生成Id重复问题

原文链接: 雪花算法(snowflake)生成Id重复问题 - 简书前言 最近工作上遇到一个雪花算法生成Id重复导致数据库中表主键冲突,导致入库失败的问题,所以顺便学习了一下雪花算法,下面是学习的笔记以及讨论如果解决雪花算法在分布式部署中生成...https://www.jianshu.com/p/71286e89e0c5 前言 最近工作上遇到一个雪花算法生成Id重复导致数据库中表主键冲突,导致入库失败的问题,所以顺便学习了一下雪花算法,下面是学习的笔记以及讨论如果解决雪花算法在分布式部署中生成重复I

大魔王 2万+

ZYNQ microblaze boot.bin固化步骤

一,ZYNQ移植软核的原理FPGA规模巨大而且功能复杂,因此设计的每一个部分都从头开始是不切实际的。一种解决的办法是:对于较为通用的部分可以重用现有的功能模块,而把主要的时间和资源用在设计中的那些全新的、独特的部分。这就像是你在开发应用程序的时候就不用直接去写驱动物理硬件的代码,而是直接调用Windows提供的API就行了。

wangjie36的博客 2782

基于STM32L4XX、HAL库的SIM65M定位模块驱动程序设计

SIM65M是一款基于4G LTE Cat.1的无线通信模块,支持最大下行速率10Mbps和上行速率5Mbps。它兼容多种网络协议(TCP/UDP/HTTP/HTTPS/FTP/MQTT等),适用于物联网应用。PC0 <---> PWRKEY (模块电源控制)PC1 <---> RESET (模块复位)支持LTE-FDD/LTE-TDD。工作电压:3.4V~4.2V。

zhusl6688的博客 196

雪花算法java版本

最近遇到了分布式架构的使用,需要全局流水号,来贯穿整个微服务,所以找到了雪花算法,网上雪花算法的例子有很多,我也是随便找了一个研究一下,测试后感觉和算法格式的差距太大,打印出来的结果只有60位,而且转成long类型貌似是18位,不过还是得感谢前辈们的努力,让我了解这个算法,根据算法内容进行了修...

chenxi312365的博客 575

SolidWorks 小车底盘 装配体

通过制作小车底盘了解solidworks装配体的部分知识

及时总结 2228

雪花算法:分布式唯一ID生成利器

前言 无论是在分布式系统中的ID生成,还是在业务系统中请求流水号这一类唯一编号的生成,都是软件开发人员经常会面临的一场景。而雪花算法便是这些场景的一个解决方案。 以分布式ID为例,它的生成往往会在唯一性、递增性、高可用性、高性能等方面都有所要求。并且在业务处理时,还要防止爬虫根据ID的自增进行数据爬取。而雪花算法,在这些方面表现得都不错。 常见分布式ID生成 市面上比较常见的分布式ID生成算法及类库: UUID:Java自带API,生成一串唯一随机36位字符串(32个字符串+4个“-”)。可以保证唯一性,但

程序新视界 3025

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

分布式序列号算法--雪花算法

分布式序列号算法分布式序列号算法雪花算法雪花算法--java实现雪花算法--存在的劣势雪花算法--存在的优点 分布式序列号算法 在目前工业界比较成熟的分布式序列号算法,推荐Twitter的一款分布式ID生成算法-雪花算法(SnowFlake) 雪花算法 SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1bit,不用,因为二进制中最高位是符号位,1表示负数,0表示正数。生成的id一般都是用整数,所以最高位固定为0。 41bit-时间戳,用来记录时间戳,毫秒级。 41位

JackieJia的博客 2071

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

分布式唯一Id(雪花算法——snowflake)

给大家分享分布式唯一id——雪花算法以及雪花算法的改进版 1.雪花算法介绍 2.传统分布式雪花算法java版 3.python版本 4.Snowflake 的其他变种 5.异常情况讨论 6.改进版snowflake 1.雪花算法介绍 Snowflake 生成的 unique ID 的组成 (由高位到低位): 41 bits: Timestamp (毫秒级) 10 bi...

qq_38247150的博客 1838

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

分布式部署ID全局配置之雪花算法

HttpClient使用(包含HttpPost及HttpGet) 简介 HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。 HttpClient最新版本是HttpClient 4.5.3 (GA)。 官方下载:http://hc.apache.org/downloads.cgi 主要特性 基于标准、纯净的Java语言,实现了HTTP1.0和HTTP1.1。 以可扩展的面向

qq_40093255的博客 3076

雪花算法【snowflake】

雪花算法 为什么需要分布式全局唯一ID 以及分布式ID的业务需求? 在复杂分布式系统中,往往需要对大量对数据和消息进行标识 如在美团、支付、餐饮 中 系统的数据日渐增长,对数据分库分表需要有一个唯一来标识一条数据或消息 此时一个能够生成全局唯一ID的系统是非常有必要的 ID生成规则部分硬性要求 全局唯一 :不能出现重复的ID,要 唯一标识 趋势递增 :在Mysql 的InnoDB引擎使用的是聚集索引,由于多数RDBMS 使用的是Btree数据结构来存储数据,在主键的选择上面我们应该尽量使用有序的主键

浪人与酒 1165

java雪花算法

【代码】java雪花算法。

专栏 137

雪花算法(Snowflake)

在生成ID的过程中,需要考虑时间戳的回拨问题,如果当前时间小于上一次生成ID的时间戳,那么就抛出一个异常。在Twitter原始的雪花算法设计中,可能并没有直接使用10位来表示工作机器ID,而是将机器ID部分进一步细分为数据中心ID和工作机器ID,其中每个部分可能占用更少的位数(如各5位)。它可以保证在分布式环境中生成的ID是唯一且有序的。这使得在同一台机器上运行的不同应用程序实例可以使用不同的工作机器ID来生成唯一的ID。它的主要功能是在分布式系统中生成一个全局唯一的ID,且ID是按照时间有序递增的。

weixin_37842058的博客 1546

分库分表下的 ID 冲突问题与雪花算法讲解

分库分表场景下传统自增ID会导致主键冲突,本文对比分析了五种分布式ID方案:改进型数据库自增ID(步长设置)、UUID(全局唯一但无序)、Redis发号器(高性能但依赖外部服务)、Snowflake算法(趋势递增)和数据库号段模式(批量化)。重点剖析了Snowflake算法的64位结构设计(时间戳41位+数据中心5位+机器ID5位+序列号12位),并提供了Java实现示例。方案选型建议根据业务场景在性能、唯一性、依赖性等维度权衡,Snowflake

chandfy的博客 1259
上一篇: Vue Springboot ElementUI实战教程
下一篇: Kafka教程(安装/配置/开发/面试题)
程猿薇茑
程猿薇茑 优质创作者: Java技术领域 优质创作者: Java技术领域 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄16年 6050粉丝 213原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程猿薇茑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值