SnowFlake 雪花算法
SnowFlake 中文意思为雪花,故称为雪花算法。最早是 Twitter 公司在其内部用于分布式环境下生成唯一 ID。在2014年开源 scala 语言版本。
实现原理
雪花算法原理就是生成一个的64位比特位的 long 类型的唯一 id。
最高1位固定值0,因为生成的 id 是正整数,如果是1就是负数了。
接下来41位存储毫秒级时间戳,以当前的时间作为值,所以是时刻改变的。2^41/(1000606024365)=69,大概可以使用69年。
再接下10位存储机器码,这是为了防止多台机器同时申请id,所以以每个机器的地址来做标记。包括5位 datacenterId 和5位 workerId。最多可以部署2^10=1024台机器。
最后12位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。为了解决一台机器同时申请id。即对于同一台机器而言,同一毫秒时间戳下,可以生成2^12=4096个不重复 id。
算法优缺点
优点
- 高并发分布式环境下生成不重复 id,每秒可生成百万个不重复 id。
- 基于时间戳,以及同一时间戳下序列号自增,基本保证 id 有序递增。
- 不依赖第三方库或者中间件。
- 算法简单,在内存中进行,效率高。
缺点
依赖服务器时间,服务器时钟回拨时可能会生成重复 id。算法中可通过记录最后一个生成 id 时的时间戳来解决,每次生成 id 之前比较当前服务器时钟是否被回拨,避免生成重复 id。
糊涂工具使用案例
引入依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
code
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
public class TigerTest {
public static void main(String[] args) {
// 参数1为终端ID
// 参数2为数据中心ID
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
long id0 = snowflake.nextId();
String id1 = snowflake.nextIdStr();
//简单使用
long id2 = IdUtil.getSnowflakeNextId();
String id3 = IdUtil.getSnowflakeNextIdStr();
Console.log("雪花算法id0:{}",id0);
Console.log("雪花算法idS0:{}",id1);
Console.log("雪花算法id1:{}",id2);
Console.log("雪花算法idStr1:{}",id3);
Console.log("当前时间戳:{}",System.currentTimeMillis());
}
}