雪花算法的原理

编程入门 行业动态 更新时间:2024-10-22 02:40:05

雪花<a href=https://www.elefans.com/category/jswz/34/1770096.html style=算法的原理"/>

雪花算法的原理

目录

前提

原理

代码

深度解析

4096

​ 69

1024

 总结


前提

需要对位运算符有所了解,运算符之位运算符

原理

1,如图所示,整个id的生成,是有三部分组合在一起的

2,第一部分是时间,站位41bit;第二部分是工作机器id,站位10bit;第三部分是序列号,站位12bit。

3,第一部分时间的生成规则是:当前时间戳【System.currentTimeMillis()】,减去初始时间【private long twepoch = 1628850054648L;】,会得到一个时间差,第一位存放的就是这个时间差。

4,第二部分工作机器id规则:有数据中心(5bit)+机器节点(5bit)组合在一起。可以满足多钟场景使用。

5,第三部分序列号规则:一个由0不断自增的整数。当处于高并发的情况下,每毫秒都需要生成大量的id时,只靠时间差来保证唯一性,已经不能满足需求了。序列号,不断自增,由序列表+时间差就能保证唯一性了。

6,核心:把如上三部分,根据前后顺序,拼接在一起,唯一id就出来了。拼接主要是利用位运算符,来实现的。

代码

/*** 生成id* 每毫秒可产生4096不同id* 最多可以使用69.73年* * @author frank—fu**/
public class IdGen {//机器节点private long workerId;//数据中心private long datacenterId;//序列号(自增)private long sequence = 0L;//初始时间(Thu, 04 Nov 2010 01:42:54 GMT)//主要是用来计算时间差(当前时间-twepoch)//这个时间最好是系统第一次上线时间,这样可以使用大概69.73年private long twepoch = 1628850054648L;//机器节点ID长度private long workerIdBits = 5L; //数据中心ID长度private long datacenterIdBits = 5L;//最大支持机器节点数0~31,一共32个private long maxWorkerId = -1L ^ (-1L << workerIdBits);//最大支持数据中心节点数0~31,一共32个private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); //序列号长度private long sequenceBits = 12L;//机器节点需要左移位数(sequenceBits = 12)private long workerIdShift = sequenceBits;//数据中心节点需要左移位数(sequenceBits + workerIdBits = 17)private long datacenterIdShift = sequenceBits + workerIdBits;//时间毫秒数需要左移位数(sequenceBits + workerIdBits + datacenterIdBits = 22)private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;//sequence的最大值4095,如果为4095,则sequence=0private long sequenceMask = -1L ^ (-1L << sequenceBits);//上次获取id的时间,默认为-1private long lastTimestamp = -1L;private static class IdGenHolder {private static final IdGen instance = new IdGen();}public static IdGen getInStance() {return IdGenHolder.instance;}public IdGen() {this(0L, 0L);}public IdGen(long workerId, long datacenterId) {if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));}if (datacenterId > maxDatacenterId || datacenterId < 0) {throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));}this.workerId = workerId;this.datacenterId = datacenterId;}public synchronized long nextId() {//获取当前毫秒数long timestamp = timeGen(); //如果服务器时间有问题(时钟后退) 报错。if (timestamp < lastTimestamp) {throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));}//如果上次生成时间和当前时间相同,在同一毫秒内if (lastTimestamp == timestamp) {//sequence自增,因为sequence只有12bit,所以和sequenceMask相与一下,去掉高位sequence = (sequence + 1) & sequenceMask;//判断是否溢出,也就是每毫秒内超过4095,当为4096时,与sequenceMask相与,sequence就等于0if (sequence == 0) {timestamp = tilNextMillis(lastTimestamp); //自旋等待到下一毫秒}} else {//如果和上次生成时间不同,重置sequence,就是下一毫秒开始,sequence计数重新从0开始累加sequence = 0L;}//保存本次生成id的时间lastTimestamp = timestamp;//核心计算//1,(timestamp - twepoch) << timestampLeftShift (当前时间减去初始时间)的值左移22位//2,datacenterId << datacenterIdShift 数据中心左移17位//3,workerId << workerIdShift 机器节点左移12位//利用|的特性,把数据拼接起来return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift)| (workerId << workerIdShift) | sequence;}protected long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}protected long timeGen() {return System.currentTimeMillis();}}

深度解析

1,为什么1毫秒最多可以产生4096个id?

2,为什么最好只能使用69年?

3,为什么最多支持1024个机器节点?

4096

序列号是12bit组成:1111 1111 1111 转成二进制 4095

 69

整个函数return的是long【public synchronized long nextId()】;long 占64bit,64-1(占位符)-10(机器)-12(序列号)= 41 bit;也就是说时间差最多只能占41bit

转成十进制,也就是2199023255551,时间差最大的值就是2199023255551毫秒。69年=2,175,984,000,000毫秒

1024

机器占10bit(数据中心(5bit)+机器节点(5bit)),1111111111 转成十进制是1023,加上0,就是1024

 总结

1,1毫秒最多产生4096个不同的id

2,最多可使用69年

3,最多可以支持1024个机器 

更多推荐

雪花算法的原理

本文发布于:2024-02-27 13:32:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1706737.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:算法   雪花   原理

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!