雪花算法(Snowflake)是一种分布式系统中生成唯一ID的算法,由Twitter开源。它能够保证在分布式环境下生成的ID是唯一的,并且具有高性能和低延迟的特点。雪花算法生成的ID是一个64位的长整型,结构如下:
- 1位符号位:始终为0,表示正数。
- 41位时间戳:表示当前时间与某个固定时间点的差值,单位是毫秒。这部分可以表示约69年的时间。
- 10位机器标识:可以包括数据中心ID和机器ID,用于标识不同的数据中心和机器。
- 12位序列号:在同一毫秒内,同一个机器可以生成的不同ID,最多可以生成4096个。
下面是一个简单的雪花算法工具类实现(Java):
```java public class SnowflakeIdWorker { // 起始的时间戳 private final static long START_TIMESTAMP = 1609459200000L;
// 机器标识:数据中心ID与机器ID的位数
private final static long DATA_CENTER_ID_BITS = 5L;
private final static long MACHINE_ID_BITS = 5L;
// 时间戳所占的位数
private final static long TIMESTAMP_LEFT_BITS = 41L;
// 机器标识所占的位数
private final static long MACHINE_ID_LEFT_BITS = 12L;
// 序列号所占的位数
private final static long SEQUENCE_LEFT_BITS = 12L;
// 机器ID向左移12位
private final static long MACHINE_ID_SHIFT = SEQUENCE_LEFT_BITS + MACHINE_ID_BITS;
// 数据中心ID向左移17位
private final static long DATA_CENTER_ID_SHIFT = SEQUENCE_LEFT_BITS + MACHINE_ID_BITS + DATA_CENTER_ID_BITS;
// 时间戳向左移22位
private final static long TIMESTAMP_LEFT_SHIFT = SEQUENCE_LEFT_BITS + MACHINE_ID_BITS + DATA_CENTER_ID_BITS;
// 序列号掩码:4095(0b00011111)
private final static long SEQUENCE_MASK = 0x3FFL;
// 机器ID
private long dataCenterId;
// 机器ID
private long machineId;
// 时间戳
private long timestamp;
// 序列号
private long sequence = 0L;
public SnowflakeIdWorker(long dataCenterId, long machineId) {
if (dataCenterId > (1L << DATA_CENTER_ID_BITS) || dataCenterId < 0) {
throw new IllegalArgumentException("Data center ID can't be greater than " + (1L << DATA_CENTER_ID_BITS) || dataCenterId < 0);
}
if (machineId > (1L << MACHINE_ID_BITS) || machineId < 0) {
throw new IllegalArgumentException("Machine ID can't be greater than " + (1L << MACHINE_ID_BITS) || machineId < 0);
}
this.dataCenterId = dataCenterId;
this.machineId = machineId;
this.timestamp = System.currentTimeMillis();
}
public synchronized long nextId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < timestamp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (timestamp - currentTimestamp) + " milliseconds");
}
if (currentTimestamp == timestamp) {
sequence = (sequence + 1) & SEQUENCE_MASK;
if (sequence == 0) {
timestamp = tilNextMillis(timestamp);
}
} else {
sequence = 0L;
timestamp = currentTimestamp;
}
return ((currentTimestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT) |
(dataCenterId << DATA_CENTER_ID_SHIFT) |
(machineId << MACHINE_ID_SHIFT) |
sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
} ```
使用示例:
java
public class Main {
public static void main(String[] args) {
SnowflakeIdWorker idWorker = new SnowflakeIdWorker(1, 1);
System.out.println(idWorker.nextId()); // 输出:1625503697882
}
}
这个工具类可以用于生成唯一的ID,可以根据实际需求进行扩展和优化。