当前位置:首页 » 《我的小黑屋》 » 正文

JAVA---雪花算法(Snowflake)实现

20 人参与  2024年09月27日 14:41  分类 : 《我的小黑屋》  评论

点击全文阅读


雪花算法(Snowflake)是Twitter开源的一种分布式唯一ID生成算法,用于在分布式系统中生成全局唯一的ID。雪花算法生成的ID是一个64位的整数,通常表示为长整型(long)。

雪花算法的结构

雪花算法生成的ID由以下几部分组成:

符号位(1位):始终为0,保证生成的ID为正数。时间戳(41位):记录生成ID的时间戳,精确到毫秒级。可以使用大约69年的时间。机器ID(10位):标识生成ID的机器,可以支持1024台机器。序列号(12位):同一毫秒内生成的多个ID的序列号,可以支持每毫秒生成4096个ID。

实现原理

时间戳

使用当前时间戳减去一个固定的起始时间戳(通常是系统启动时间或一个固定的过去时间),得到一个相对时间戳。41位的时间戳可以表示的最大值是2^41 - 1,大约是69年。

机器ID

每个生成ID的机器都有一个唯一的机器ID,通常由数据中心ID和机器ID组成,共10位,可以支持1024台机器。

序列号

在同一毫秒内,如果生成的ID数量超过4096个,则需要等待下一毫秒再生成新的ID。序列号从0开始递增,每生成一个ID,序列号加1,直到达到4095,然后重置为0。

生成ID的步骤

获取当前时间戳

获取当前系统时间戳(毫秒级),减去起始时间戳,得到相对时间戳。

检查时间戳是否发生变化

如果当前时间戳与上一次生成ID的时间戳相同,则序列号加1。如果序列号达到4095,则等待下一毫秒再生成新的ID。

组装ID

将符号位、时间戳、机器ID和序列号按位拼接,生成最终的64位ID。

示例代码

以下是一个简单的雪花算法实现示例:

public class SnowflakeIdGenerator {    private final long twepoch = 1288834974657L; // 起始时间戳,例如Twitter的Snowflake起始时间    private final long workerIdBits = 10L;    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);    private final long sequenceBits = 12L;    private final long workerIdShift = sequenceBits;    private final long timestampLeftShift = sequenceBits + workerIdBits;    private final long sequenceMask = -1L ^ (-1L << sequenceBits);    private long workerId;    private long sequence = 0L;    private long lastTimestamp = -1L;    public SnowflakeIdGenerator(long workerId) {        if (workerId > maxWorkerId || workerId < 0) {            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));        }        this.workerId = workerId;    }    public synchronized long nextId() {        long timestamp = timeGen();        if (timestamp < lastTimestamp) {            throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));        }        if (lastTimestamp == timestamp) {            sequence = (sequence + 1) & sequenceMask;            if (sequence == 0) {                timestamp = tilNextMillis(lastTimestamp);            }        } else {            sequence = 0L;        }        lastTimestamp = timestamp;        return ((timestamp - twepoch) << timestampLeftShift) |                (workerId << workerIdShift) |                sequence;    }    protected long tilNextMillis(long lastTimestamp) {        long timestamp = timeGen();        while (timestamp <= lastTimestamp) {            timestamp = timeGen();        }        return timestamp;    }    protected long timeGen() {        return System.currentTimeMillis();    }    public static void main(String[] args) {        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1);        System.out.println(idGenerator.nextId());    }}

总结

雪花算法通过组合时间戳、机器ID和序列号,生成全局唯一的64位ID。这种算法简单高效,适用于分布式系统中唯一ID的生成需求。通过合理配置机器ID和起始时间戳,可以满足不同规模和需求的系统。


点击全文阅读


本文链接:http://zhangshiyu.com/post/165387.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1