JAVA---雪花算法(Snowflake)实现
CSDN 2024-09-13 11:35:01 阅读 96
雪花算法(Snowflake)是Twitter开源的一种分布式唯一ID生成算法,用于在分布式系统中生成全局唯一的ID。雪花算法生成的ID是一个64位的整数,通常表示为长整型(long)。
雪花算法的结构
雪花算法生成的ID由以下几部分组成:
符号位(1位):始终为0,保证生成的ID为正数。时间戳(41位):记录生成ID的时间戳,精确到毫秒级。可以使用大约69年的时间。机器ID(10位):标识生成ID的机器,可以支持1024台机器。序列号(12位):同一毫秒内生成的多个ID的序列号,可以支持每毫秒生成4096个ID。
实现原理
时间戳:
使用当前时间戳减去一个固定的起始时间戳(通常是系统启动时间或一个固定的过去时间),得到一个相对时间戳。41位的时间戳可以表示的最大值是<code>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和起始时间戳,可以满足不同规模和需求的系统。
上一篇: 【C语言必学知识点七】你知道在动态内存管理中存在的内存泄露问题吗?遇到内存泄露时应该如何处理?今天跟你好好介绍一下如何正确使用calloc与realloc!!!
下一篇: 民宿|基于java的民宿推荐系统(源码+数据库+文档)
本文标签
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。