您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

雪花算法

时间:2022-08-16 14:39:47  来源:  作者:雪地大懒猫

雪花算法

SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的。本文主要是是实现了单机版本的算法,使用多台计算机构成分布式的ID生成服务也是可以的,预留了相关的方法参数。

应用范围

1、在jdk中自带的uuid算法可以来生成唯一性的32位字符串【拼接上‘-’之后,是36位,如:’
4211210a-ba56-41b4-b055-6262411970a4’】,uuid算法得到的id是无序的,而且是字符串,数据表记录多时,查询效率不高

2、基于数据库的sequnce【通过表也可以模拟sequence】来生成,在分布式系统中更新记录不方便,只能操作主表的更新。

3、雪花算法在分布式系统中可以较好地使用。

原理

把64位进行拆分,分为如下几个部份

第1部份只占1位,而且必需为0,因为最高位0表示正数。

第2部份是时间戳,占41位【为什么是41位,后面会介绍】,最多可以表示2^41,大约是69年

第3部份是产生的机器号,占10位【也可以是其它位数,不一定非得是10位,官方约定是10位】,最多可以表示2^10,相当于1024台机器,这部分可以划成两个维度,如下:

3.1 拿5位出来做为机房号,最多可以表示 2^5个机房号,也就是最多32个机房编号

3.2 拿5位出来做为机器号,最多可以表示 2^5台电脑,也就是最多32台电脑编号

第4部份是时间戳,占12位,相当于在同一个毫秒内,可以最大支持2^12,也就是4096个序号【普通的计算机根本达不到】

代码实现

 

public class IdGenerator {

 

//定义属性 [机器码10位,如何分配成 机房码和电脑码,做为属性,这里默认都是5]

private final long dataCenterBits = 5L; //机房码的位数

private final long computerBits = 5L; //电脑码的位数

//最后的序列码,默认从0开始

private long sequence = 0L;

//记录执行的最后时间,以毫秒为单位,默认初始化为-1L

private long lastTimeStamp = -1L;

 

//因为要做二进制运算,我们需要定义如下属性来记录每个部份所在的位置的偏移量

private final long sequenceBits = 12; //序号占用12位

private final long computerIdShift = sequenceBits; //电脑码的偏移量

private final long dataCenterIdShift = computerIdShift + computerBits; //机房码的偏移量

private final long timeStampShift = dataCenterIdShift + dataCenterBits; //时间戳的偏移量

 

//根据机房码的位数,来计算出机房码最大值

private final long MAX_DATA_CENTER = -1L ^ (-1L << dataCenterBits); //相当于 11111, 也就是 31

private final long MAX_COMPUTER = -1L ^ (-1L << computerBits); //同上

private final long SEQUENCE_MASK = -1L ^ (-1L << sequenceBits); // 为防止序列号溢出而准备的掩码,相当于 11111111 111

 

//定义属性

private long computerId; //电脑的id 【在分布式系统中,记录这个雪花号是由哪一台电脑生成的】

private long dataCenterId; //机房的id 【在分布式系统中,记录这个雪花号是由哪一个中心机房里的电脑生成的】

//构造

public IdGenerator(long computerId, long dataCenterId) {

//对参数的有效性进行判断,由于机房码和电脑码都是5位,所以,它们的值最大都不能超过31

if(computerId > MAX_COMPUTER || computerId < 0) {

throw new IllegalArgumentException(String.format("电脑编号不能大于 %d 或者小于 %d n",MAX_COMPUTER,0));

}

if(dataCenterId > MAX_DATA_CENTER || dataCenterId < 0) {

throw new IllegalArgumentException(String.format("机房编号不能大于 %d 或者小于 %dn",MAX_DATA_CENTER, 0));

}

//赋值

this.computerId = computerId;

this.dataCenterId = dataCenterId;

}

/***************

* 核心方法,利用雪花算法来获取一个唯一性的ID

* @return

*/

public synchronized long nextId() {

//1.获取当前的系统时间

long currTime = getCurrentTime();

//2. 判断是否在同一个时间内的请求

if(currTime == lastTimeStamp) {

//2.1 sequence 要增1, 但要预防sequence超过 最大值4095,所以要 与 SEQUENCE_MASK 按位求与

sequence = (sequence + 1) & SEQUENCE_MASK;

//2.2 进一步判断,如果在同一个毫秒内,sequence达到了4096【1 0000 0000 0000】,则lastTime时间戳必需跳入下一个时间,因为同一个毫秒内

//sequence只能产生4096个【0-4095】,当超过时,必需跳入下一个毫秒

// 【此情况极少出现,但不可不防,这意味着1个毫秒内,JVM要执行此方法达到4096次,我这个电脑执行远达不到。】

if(sequence == 0) {

currTime = unitNextTime();

}

} else {

//如果不是与lastTime一样,则表示进入了下一个毫秒,则sequence重新计数

sequence = 0L;

}

//3. 把当前时间赋值给 lastTime, 以便下一次判断是否处在同一个毫秒内

lastTimeStamp = currTime;

//4. 依次把各个部门求出来并通过逻辑或 拼接起来

return (this.lastTimeStamp << timeStampShift) | //把当前系统时间 左移22位

(this.dataCenterId << dataCenterIdShift) | //把机房编号 左移17位

(this.computerId << computerIdShift) | //把计算机号编号左移 12位

this.sequence; //最后的序列号占12位,无需移动

}

 

/******

* 等待毫秒数进入下一个时间

* @return

*/

private long unitNextTime() {

//1.再次获取系统时间

long timestamp = getCurrentTime();

//2. 判断 lastTime与currentTime是否一样

while(timestamp <= lastTimeStamp) {

//2.1 继续获取系统时间,直到上面的条件不成立为止

timestamp = getCurrentTime();

}

//3. 返回

return timestamp;

}

 

/*****

* 用来获取当前的系统时间,以毫秒为单位

* @return

*/

private long getCurrentTime() {

return System.currentTimeMillis();

}

}

 

测试类

 

public class UseIdGenerator {

/****

* 主方法

* @param args

*/

public static void mAIn(String[] args) {

//这里两个参数都是1,表示1号机房和1号电脑【在分布式系统中,每个电脑知道自己所在的机房和编号】

IdGenerator ig = new IdGenerator(1,1);

//循环生成

long result = -1;

for(int i = 0;i<100000;i++) {

result = ig.nextId();

System.out.println(result+" , "+Long.toBinaryString(result));

}

}

 

}



Tags:雪花算法   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
雪花算法详解与Java实现:分布式唯一ID生成原理
SnowFlake 算法,是 Twitter 开源的分布式 ID 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 ID。在分布式系统中的应用十分广泛,且 ID 引入了时间戳...【详细内容】
2024-02-03  Search: 雪花算法  点击:(51)  评论:(0)  加入收藏
聊一聊雪花算法与分布式ID生成
生成全局唯一ID的雪花算法原理雪花算法是一种用于生成全局唯一ID的算法,最初由Twitter开发,用于解决分布式系统中生成ID的问题。其核心思想是将一个64位的长整型ID划分成多个...【详细内容】
2023-12-12  Search: 雪花算法  点击:(136)  评论:(0)  加入收藏
你可能听说过雪花算法
雪花算法介绍雪花算法(Snowflake)是一种分布式唯一ID生成算法,用于生成全局唯一的ID。它的设计目标是在分布式系统中生成ID,保证ID的唯一性、有序性和趋势递增。雪花算法的核心...【详细内容】
2023-11-10  Search: 雪花算法  点击:(202)  评论:(0)  加入收藏
什么是雪花算法?啥原理?附Java实现!
SnowFlake 算法,是 Twitter 开源的分布式 ID 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 ID。在分布式系统中的应用十分广泛,且 ID 引入了时间戳...【详细内容】
2023-03-09  Search: 雪花算法  点击:(149)  评论:(0)  加入收藏
记一次“雪花算法”造成的生产事故的排查记录
本文主要内容如下: 前言最近生产环境遇到一个问题:现象:创建工单、订单等地方,全都创建数据失败。初步排查:报错信息为duplicate key,意思是保存数据的时候,报主键 id 重复,而这些...【详细内容】
2022-11-15  Search: 雪花算法  点击:(202)  评论:(0)  加入收藏
雪花算法
雪花算法SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入...【详细内容】
2022-08-16  Search: 雪花算法  点击:(668)  评论:(0)  加入收藏
面试官:讲讲雪花算法,越详细越好
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯&middot;奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  Search: 雪花算法  点击:(329)  评论:(0)  加入收藏
聊聊大厂都在用的雪花算法
原文出自:公众号 盼盼编程原文链接: https://mp.weixin.qq.com/s/rz7l1yfZvPtXv74dOYyKEA前言以前用rand和srand生成过伪随机数,伪随机数的序列是固定的,今天学习生成真正的随机...【详细内容】
2021-08-26  Search: 雪花算法  点击:(459)  评论:(0)  加入收藏
JPA自定义ID生成器,雪花算法实现代码分享
本文分享下Spring boot项目下使用JPA操作数据库时关于ID生成器的相关实现代码。在JPA中一个数据表必须要有主键,主键类型一般是推荐使用Long类型,那么在分布式微服务下需要保...【详细内容】
2021-08-17  Search: 雪花算法  点击:(1782)  评论:(0)  加入收藏
分布式ID生成--雪花算法
导读:唯一ID可以标识数据的唯一性,在分布式系统中生成唯一ID的方案有很多,常见的方式大概有以下三种 依赖数据库,使用如MySQL自增列或Oracle序列等。 UUID随机数 snowflake雪花...【详细内容】
2019-09-05  Search: 雪花算法  点击:(974)  评论:(0)  加入收藏
▌简易百科推荐
小红书、视频号、抖音流量算法解析,干货满满,值得一看!
咱们中国现在可不是一般的牛!网上的网友已经破了十个亿啦!到了这个互联网的新时代,谁有更多的人流量,谁就能赢得更多的掌声哦~抖音、小红书、、视频号,是很多品牌必争的流量洼地...【详细内容】
2024-02-23  二手车小胖说    Tags:流量算法   点击:(14)  评论:(0)  加入收藏
雪花算法详解与Java实现:分布式唯一ID生成原理
SnowFlake 算法,是 Twitter 开源的分布式 ID 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 ID。在分布式系统中的应用十分广泛,且 ID 引入了时间戳...【详细内容】
2024-02-03   一安未来  微信公众号  Tags:雪花算法   点击:(51)  评论:(0)  加入收藏
程序开发中常用的十种算法,你用过几种?
当编写程序时,了解和使用不同的算法对解决问题至关重要。以下是C#中常用的10种算法,每个算法都伴随着示例代码和详细说明。1. 冒泡排序 (Bubble Sort):冒泡排序是一种简单的比...【详细内容】
2024-01-17  架构师老卢  今日头条  Tags:算法   点击:(45)  评论:(0)  加入收藏
百度推荐排序技术的思考与实践
本文将分享百度在推荐排序方面的思考与实践。在整个工业界的推广搜场景上,特征设计通常都是采用离散化的设计,需要保证两方面的效果,一方面是记忆,另一方面是泛化。特征都是通过...【详细内容】
2024-01-09  DataFunTalk  微信公众号  Tags:百度推荐   点击:(77)  评论:(0)  加入收藏
什么是布隆过滤器?如何实现布隆过滤器?
以下我们介绍了什么是布隆过滤器?它的使用场景和执行流程,以及在 Redis 中它的使用,那么问题来了,在日常开发中,也就是在 Java 开发中,我们又将如何操作布隆过滤器呢?布隆过滤器(Blo...【详细内容】
2024-01-05  Java中文社群  微信公众号  Tags:布隆过滤器   点击:(87)  评论:(0)  加入收藏
面向推荐系统的深度强化学习算法研究与应用
随着互联网的快速发展,推荐系统在各个领域中扮演着重要的角色。传统的推荐算法在面对大规模、复杂的数据时存在一定的局限性。为了解决这一问题,深度强化学习算法应运而生。本...【详细内容】
2024-01-04  数码小风向    Tags:算法   点击:(96)  评论:(0)  加入收藏
非负矩阵分解算法:从非负数据中提取主题、特征等信息
非负矩阵分解算法(Non-negativeMatrixFactorization,简称NMF)是一种常用的数据分析和特征提取方法,主要用于从非负数据中提取主题、特征等有意义的信息。本文将介绍非负矩阵分解...【详细内容】
2024-01-02  毛晓峰    Tags:算法   点击:(64)  评论:(0)  加入收藏
再谈前端算法,你这回明白了吗?
楔子 -- 青蛙跳台阶一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶,求该青蛙跳上一个n级的台阶总共需要多少种跳法。分析: 当n=1的时候,①只需要跳一次即可;只有一种跳法,即f(...【详细内容】
2023-12-28  前端爱好者  微信公众号  Tags:前端算法   点击:(108)  评论:(0)  加入收藏
三分钟学习二分查找
二分查找是一种在有序数组中查找元素的算法,通过不断将搜索区域分成两半来实现。你可能在日常生活中已经不知不觉地使用了大脑里的二分查找。最常见的例子是在字典中查找一个...【详细内容】
2023-12-22  小技术君  微信公众号  Tags:二分查找   点击:(78)  评论:(0)  加入收藏
强化学习算法在资源调度与优化中的应用
随着云计算和大数据技术的快速发展,资源调度与优化成为了现代计算系统中的重要问题。传统的资源调度算法往往基于静态规则或启发式方法,无法适应动态变化的环境和复杂的任务需...【详细内容】
2023-12-14  职场小达人欢晓    Tags:算法   点击:(165)  评论:(0)  加入收藏
站内最新
站内热门
站内头条