雪花算法是什么
答案
雪花算法(Snowflake Algorithm)是 Twitter 开发的一种分布式唯一 ID 生成算法,使用 64 位长整型,通过 时间戳、机器 ID 和 序列号 的组合,在分布式系统中生成全局唯一的 ID。它高效、有序,适合分布式环境下的主键或标识生成。
关键事实
- 结构(64 位):
- 1 位:符号位(0)。
- 41 位:时间戳(毫秒级,约 69 年)。
- 10 位:机器 ID(支持 1024 台机器)。
- 12 位:序列号(每毫秒 4096 个 ID)。
- 生成方式:
- 时间戳确保趋势递增,机器 ID 区分节点,序列号处理同一毫秒内的请求。
- 特点:
- 唯一性:全局唯一。
- 有序性:时间单调递增。
- 高性能:每秒可生成百万 ID。
实现原理
- 流程:
- 获取当前毫秒时间戳(相对起始时间)。
- 同一毫秒内,序列号递增(0-4095)。
- 时间戳变化,序列号重置。
- 组合:
(时间戳 << 22) | (机器ID << 12) | 序列号
。 - 示例:
- 时间戳:1234567890ms。
- 机器 ID:1。
- 序列号:0。
- ID:
(1234567890 << 22) | (1 << 12) | 0
。
代码(简版)
public class Snowflake {
private long workerId = 1;
private long sequence = 0;
private long lastTimestamp = -1;
private final long epoch = 1577836800000L; // 2020-01-01
public synchronized long nextId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) throw new RuntimeException("Clock moved backwards");
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & 4095; // 12 位掩码
if (sequence == 0) timestamp = waitNextMillis(lastTimestamp);
} else {
sequence = 0;
}
lastTimestamp = timestamp;
return ((timestamp - epoch) << 22) | (workerId << 12) | sequence;
}
private long waitNextMillis(long last) {
long now = System.currentTimeMillis();
while (now <= last) now = System.currentTimeMillis();
return now;
}
}
特点
- 优点:
- 高吞吐量:每毫秒 4096 个 ID。
- 有序性:便于数据库索引。
- 分布式:机器 ID 区分节点。
- 缺点:
- 时钟回拨:系统时间倒退可能重复。
- 配置依赖:机器 ID 需分配。
延伸与面试角度
- 时钟回拨解决:
- 等待时间追上。
- 加版本号(如
AtomicStampedReference
)。 - 应用场景:
- 分布式订单号。
- 数据库主键。
- 与 UUID 对比:
- UUID:128 位,无序,随机。
- Snowflake:64 位,有序,高效。
- 面试点:
- 问“结构”时,提 41-10-12 分配。
- 问“问题”时,提时钟回拨。
总结
雪花算法用 64 位组合时间戳、机器 ID 和序列号生成唯一 ID,高效有序,适合分布式系统。面试时,可简述结构或写代码,突出原理和场景,展示理解深度。