介绍
在互联网公司的业务中,许多应用是分布式部署的, 分布式系统已事实上成为互联网公司各个应用的基础底座。
在分布式系统中,生成全局唯一ID对于业务的正确性至关重要。
雪花算法作为一种分布式ID生成算法,已被许多公司所采用,作为唯一ID生成器。
本文简要介绍下雪花算法的原理,以及Java代码实现。
雪花算法原理
雪花算法主要由时间戳、机器标识、序列号组成,共同构成了一个64位的全局唯一ID。
时间戳保证了ID是按时间顺序递增,不会重复。
序列号解决了同一毫秒内并发生成ID时的问题。
机器标识部分确保了在多节点部署环境中,每个节点生成的ID是唯一的。
Java代码实现示例
public class IdGenerator {
/**
* 定义起始时间戳 2024-01-01
*/
private static final long START_TIME_MILL = 1717987200000L;
/**
* 节点标识位数
*/
private static final long NODE_BIT_COUNT = 10;
/**
* 序列号位数
*/
private static final long SEQUENCE_BIT_COUNT = 12;
/**
* 节点id
*/
private static long nodeId = 0;
/**
* 序列号
*/
private static long sequenceId = 0;
private static long lastTime = -1;
public static long generateId() {
long time = System.currentTimeMillis() - START_TIME_MILL;
if (time < lastTime) {
throw new RuntimeException("time is small than lastTime");
}
if (time == lastTime) {
sequenceId = (sequenceId + 1) & ((1 << SEQUENCE_BIT_COUNT) - 1);
if (sequenceId == 0) {
time = tilNextMillis(lastTime);
}
} else {
sequenceId = 0;
}
lastTime = time;
return ((time << (NODE_BIT_COUNT + SEQUENCE_BIT_COUNT)) | (nodeId << SEQUENCE_BIT_COUNT) | sequenceId);
}
private static long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis() - START_TIME_MILL;
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis() - START_TIME_MILL;
}
return timestamp;
}
}