背景
雪花算法解决的问题是,如何在分布式环境下产生一个唯一的id,而这些唯一id在业务或者技术上都会有广泛使用,
比如订单号,一次请求的requestId,traceId等;现有的一些算法比如微软的UUID,他能保证唯一,但是雪花算法
相较于他更有优势的一点,它能保证整体递增,这对我们业务类的id很有用;取名的出处是,世界上找不到两片相同的
雪花
,在我们rpc的框架中,也用到了雪花算法来生成request-id;
算法
雪花算法的ID占用64bit,其中分别有不同的含义,第一位bit是符号位,因为我们时间都是正的,所以为0;后续41位为
时间,接着5位datacenterId+5位workerId,最后12bit位sequence表示单机在同一毫秒可以产生的id数量,所以能到单机400w
的并发
实现
- 代码实现非常简单,而且单机非常高效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25//用户自己定义的业务起始值,相当于magic num的概念
private final long twepoch = 1288834974657L;
private long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
LOGGER.error("clock is moving backwards. Rejecting requests until {}.", lastTimestamp);
throw new RuntimeException(
"Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) +
" milliseconds");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}
lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) |
(workerId << workerIdShift) | sequence;
}总结
雪花算法被广泛的应用,当然工业级别的id生成算法还有很多,包括美团的leaf
百度的UidGenerator
百度使用未来时间,存放到RingBuffer中,再次提升雪花算法的并发度,能到单机600w