当前位置: 首页 > news >正文

Java 雪花算法:分布式唯一ID生成的魔法秘籍

欢迎来到本次博客的旅程,今天我们要揭开一个神秘算法的面纱,它就是在分布式系统中广受欢迎的——雪花算法(Snowflake)。这个算法不是用来预测雪花的形状,而是用来生成唯一的ID,保证在分布式系统中,每一个ID都是独一无二的。接下来,我将带领大家一步一步深入了解这个神奇的算法,并教你如何在Java中实现它。准备好了吗?让我们开始吧!

一、什么是雪花算法?

雪花算法由Twitter在2010年发布,用于生成分布式系统中的唯一ID。想象一下,你有一大片雪花,每一片都独一无二,这就是雪花算法的工作原理。它生成的ID不仅唯一,还按时间有序。

雪花算法生成的ID是一个64位的整数,这个整数由以下几部分组成:

  • 1位的符号位,总是0,表示正数。
  • 41位的时间戳,精确到毫秒,可以使用约69年。
  • 10位的机器ID,表示最多支持1024个节点。
  • 12位的序列号,每毫秒可以生成4096个不同的ID。

这样组合在一起,就形成了一个唯一的ID。

二、为什么要用雪花算法?

在分布式系统中,生成唯一的ID是一个常见问题。常见的方法有UUID和数据库自增ID,但它们都有各自的缺点:

  • UUID:虽然唯一,但长度较长,不利于存储和索引。
  • 数据库自增ID:需要依赖数据库,不利于分布式扩展。

相比之下,雪花算法生成的ID短小精悍,按时间有序,非常适合在分布式系统中使用。

三、雪花算法的工作原理

让我们通过一个示例,详细了解雪花算法是如何工作的。

假设我们在2024年1月1日开始使用雪花算法生成ID,机器ID为1,每毫秒生成的序列号从0开始。

  1. 获取当前时间戳:获取当前时间戳(以毫秒为单位),减去一个固定的时间起点(例如2024年1月1日的时间戳),得到时间差。
  2. 拼接机器ID和序列号:将机器ID和序列号拼接在时间戳之后,形成一个64位的ID。

举个例子,如果当前时间戳是1000毫秒,机器ID是1,序列号是0,那么生成的ID就是:

ID = 时间戳 << 22 | 机器ID << 12 | 序列号= 1000 << 22 | 1 << 12 | 0= 4194304000
四、Java实现雪花算法

接下来,我们在Java中实现雪花算法。这个实现包含了基本的ID生成逻辑,以及一些必要的同步控制,确保在高并发环境下的正确性。

public class SnowflakeIdGenerator {// 起始时间戳private final long twepoch = 1577836800000L; // 2020-01-01// 机器ID所占的位数private final long workerIdBits = 5L;// 数据中心ID所占的位数private final long datacenterIdBits = 5L;// 支持的最大机器IDprivate final long maxWorkerId = -1L ^ (-1L << workerIdBits);// 支持的最大数据中心IDprivate final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);// 序列在ID中占的位数private final long sequenceBits = 12L;// 机器ID向左移12位private final long workerIdShift = sequenceBits;// 数据中心ID向左移17位private final long datacenterIdShift = sequenceBits + workerIdBits;// 时间戳向左移22位private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;// 生成序列的掩码,这里为4095private final long sequenceMask = -1L ^ (-1L << sequenceBits);private long workerId; // 机器IDprivate long datacenterId; // 数据中心IDprivate long sequence = 0L; // 序列号private long lastTimestamp = -1L; // 上次生成ID的时间戳// 构造函数public SnowflakeIdGenerator(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;}// 生成IDpublic 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 + 1) & sequenceMask;if (sequence == 0) {timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;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();}
}

以上代码中,SnowflakeIdGenerator 类实现了雪花算法的核心逻辑。让我们来逐步解释每一个部分。

  • 变量定义:定义了机器ID、数据中心ID、序列号以及时间戳等变量。
  • 构造函数:初始化机器ID和数据中心ID,并进行合法性检查。
  • nextId 方法:生成唯一ID,使用同步关键字保证线程安全。
  • tilNextMillis 方法:阻塞直到下一毫秒,以防止生成重复ID。
  • timeGen 方法:获取当前时间戳。
五、使用示例

现在,我们可以创建 SnowflakeIdGenerator 的实例,并生成唯一ID了。

public class Main {public static void main(String[] args) {SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);for (int i = 0; i < 10; i++) {long id = idGenerator.nextId();System.out.println("Generated ID: " + id);}}
}

以上代码将生成10个唯一ID,并打印到控制台。

六、结论

雪花算法在分布式系统中生成唯一ID方面表现卓越。通过详细的解释和Java实现,希望你已经掌握了这个强大的工具。无论你是在开发大型分布式系统,还是需要生成唯一ID,雪花算法都是一个值得信赖的选择。

希望这篇博客不仅帮助你理解了雪花算法,还能让你在实现过程中获得乐趣。如果你有任何问题或建议,欢迎在评论区留言,我们一起探讨!

祝编码愉快!

相关文章:

Java 雪花算法:分布式唯一ID生成的魔法秘籍

欢迎来到本次博客的旅程&#xff0c;今天我们要揭开一个神秘算法的面纱&#xff0c;它就是在分布式系统中广受欢迎的——雪花算法&#xff08;Snowflake&#xff09;。这个算法不是用来预测雪花的形状&#xff0c;而是用来生成唯一的ID&#xff0c;保证在分布式系统中&#xff…...

mybatis配置环境流程

mybatis配置环境流程 为啥要用mybatis&#xff1a;通过Mybatis实现快速访问后端pgsql、mysql等数据库。 1.修改pom.xml&#xff0c;添加mybatis相关依赖 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-s…...

UE5增强输入系统入门

UE4直接在项目设置里设置的轴映射和操作映射在UE5中被标记为废弃&#xff0c;改为使用增强输入系统。 这两天学习了下蓝图和c中增强输入系统的使用&#xff0c;在这里分享一下。 学习使用的模板是第三人称模板(蓝图/c)&#xff0c;代码蓝图都参考的模板。 增强输入系统 UE5…...

Python 语法好乱:深度解析与应对策略

Python 语法好乱&#xff1a;深度解析与应对策略 Python&#xff0c;作为一门简洁明了的编程语言&#xff0c;广受编程初学者的喜爱。然而&#xff0c;随着学习的深入&#xff0c;许多学习者会发现Python的语法似乎并不像初看起来那么简单&#xff0c;甚至有时会感到“好乱”。…...

移动端框架:加速移动应用开发与提升跨平台兼容性

在当今快速发展的移动应用领域&#xff0c;开发者们面临着如何快速构建、维护并发布跨平台应用的挑战。为了应对这一挑战&#xff0c;移动端框架应运而生&#xff0c;它们不仅加速了移动应用的开发流程&#xff0c;还提升了应用的跨平台兼容性&#xff0c;并确保了应用性能与原…...

Linux systemctl:掌握软件启动和关闭的利器

Linux systemctl&#xff1a;掌握软件启动和关闭的利器 在 Linux 操作系统中&#xff0c;systemctl 是一个强大的工具&#xff0c;用于管理系统服务的启动、停止和状态监控。本篇博客将深入介绍 systemctl 的使用方法&#xff0c;帮助你更好地掌握软件的启动和关闭。 1. syst…...

Jmeter干货分享:当你的Log viewer不显示日志时,可能是引入的Jar包冲突导致

问题描述 近期使用Jmeter时发现了一个非常奇怪的问题&#xff0c;就是Jmeter是可以正常使用运行脚本&#xff0c;但是在Log viewer中确没有任何日志&#xff0c;如下图&#xff1a; 问题排查过程 真是百思不得其解啊&#xff0c;在网上各种获取资料&#xff0c;大多数都是说跟…...

网络编程TCP

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:Java网络编程(下)&#x1f649; &#x1f439;今日诗词: 壮士当唱大风哥, 宵小之徒能几何&#xff1f;&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微…...

C++中的迭代器

目录 摘要 迭代器类别 1. 输入迭代器&#xff08;Input Iterator&#xff09; 2. 输出迭代器&#xff08;Output Iterator&#xff09; 3. 前向迭代器&#xff08;Forward Iterator&#xff09; 4. 双向迭代器&#xff08;Bidirectional Iterator&#xff09; 5. 随机访…...

8.1 Go 包的概念与使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

第一篇【传奇开心果系列】AI工业应用经典算法和Python示例:基于AI的智能制造技术经典算法与Python实践

传奇开心果博文系列 系列博文目录AI工业应用经典算法和Python示例系列 博文目录前言一、AI在智能制造方面的应用场景介绍二、基于AI的智能制造技术经典算法介绍三、支持向量机机器学习算法Python示例代码四、随机森林机器学习算法Python示例代码五、深度学习算法Python示例代码…...

Mathtype插入编号的高级格式会重置之前的简单格式的问题

文章标题没说人话&#xff0c;大致意思是&#xff1a; 先以简单格式插入几个编号 再设置高级格式的编号时&#xff0c;即使没有选择插入编号&#xff0c;在点击下图的确定键时&#xff0c;会连带前面的简单公式一并更新 我在网上没有找到相关的问题&#xff0c;即使关闭了…...

弘君资本:存储芯片概念强势,西测测试三连板,佰维存储涨超10%

存储芯片概念3日盘中强势拉升&#xff0c;截至发稿&#xff0c;西测测验、万润科技涨停&#xff0c;佰维存储涨超10%&#xff0c;香农芯创涨近7%&#xff0c;航天智装、普冉股份等涨超5%。值得注意的是&#xff0c;西测测验已连续3个交易日涨停。 职业方面&#xff0c;当时干流…...

【机器学习】逻辑回归:原理、应用与实践

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 逻辑回归&#xff1a;原理、应用与实践引言1. 逻辑回归基础1.1 基本概念1.2 Sig…...

C++:list模拟实现

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;list模拟实现》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&#xf…...

植物大战僵尸杂交版全平台 PC MAC 安卓手机下载安装详细图文教程

最近植物大战僵尸杂交版非常的火&#xff0c;好多小伙伴都想玩一玩&#xff0c;但作者只分享了 win 版&#xff0c;像手机还有MAC电脑都没有办法安装&#xff0c;身为 MAC 党当然不能放弃&#xff0c;经过一番折腾&#xff0c;也是成功在所有平台包括手机和MAC电脑都成功安装上…...

发送Http请求的两种方式

说明&#xff1a;在项目中&#xff0c;我们有时会需要调用第三方接口&#xff0c;获取调用结果&#xff0c;来实现自己的业务逻辑。调用第三方接口&#xff0c;通常是双方确定好&#xff0c;由对方开放一个接口&#xff0c;需要我们根据他们提供的接口文档&#xff0c;组装Http…...

【算法训练记录——Day23】

Day23——二叉树Ⅸ 669.修剪二叉搜索树108.将有序数组转换为二叉搜索树538.把二叉搜索树转换为累加树 今日内容&#xff1a; ● 669.修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树 ● 总结篇 669.修剪二叉搜索树 思路&#xff1a;主要是…...

【wiki知识库】04.SpringBoot后端实现电子书的增删改查以及前端界面的展示

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;今日内容 二、&#x1f30f;前端页面的改造 2.1新增电子书管理页面 2.2新增路由规则 2.3修改the-header代码 三、&#x1f697;SpringBoot后端Ebook模块改造 3.1增加电子书增/改接口 3.1.…...

NTLM Relay Gat:自动化NTLM中继安全检测工具

关于NTLM Relay Gat NTLM Relay Gat是一款功能强大的NTLM中继威胁检测工具&#xff0c;该工具旨在利用Impacket工具套件中的ntlmrelayx.py脚本在目标环境中实现NTLM中继攻击风险检测&#xff0c;以帮助研究人员确定目标环境是否能够抵御NTLM中继攻击。 功能介绍 1、多线程支持…...

摸鱼大数据——Hive函数14

14、开窗(开列)函数 官网链接&#xff1a;Window Functions - Apache AsterixDB - Apache Software Foundation 14.1 基础使用 开窗函数格式: 开窗函数 over(partition by 分组字段名 [order by 排序字段名 asc|desc] [rows between 开窗开始 and 开窗结束]) ​ partition b…...

elasticsearch的常规操作--增删改查和批量处理

1、_cat 查询 GET /_cat/nodes&#xff1a; 查看所有节点 GET /_cat/health&#xff1a; 查看es 健康状况 GET /_cat/master&#xff1a; 查看主节点 GET /_cat/indices&#xff1a;查看所有索引show databases; 2、索引一个文档&#xff08;保存&#xff09; 保存一个数据&…...

盘点2024年还在活跃发版的开源私有网盘项目附源码链接

时不时的会有客户上门咨询&#xff0c;丰盘ECM是不是开源项目&#xff0c;源码在哪里可以下载&#xff1b;如果需要和内部其他系统做集成&#xff0c;购买商业版的话&#xff0c;能否提供源代码做二次开发呢&#xff0c;等等诸多问题。 这里做个统一回复&#xff0c;丰盘ECM产…...

MySQL 使用方法以及教程

一、引言 MySQL是一个流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛应用于Web开发、数据分析等领域。它提供了高效、稳定的数据存储和查询功能。同时&#xff0c;Python作为一种强大的编程语言&#xff0c;也提供了多种与MySQL交互的库&#…...

算法学习笔记——二进制

二进制 负数的十进制转二进制数&#xff08;-2 -> 1110&#xff09;&#xff1a; 正数 - 1&#xff0c;再取反&#xff0c;得到负数的二进制。 例如&#xff1a;-2 &#xff1a;0010 -> 0010 - 1 -> 0001 -> 取反 -> 1110 负数的二进制转十进制&#xff08;…...

计算机网络介绍

计算机网络介绍 概述网络概述相关硬件 链路层VLAN概念VLAN 特点VLAN 的划分帧格式端口类型原理 STP概念特点原理 Smart Link概念特点组网 网络层ARP概念原理 IP概念版本IP 地址 IPv4IP 地址数据报格式 IPv6特点IP 地址数据报格式 ICMP概念分类报文格式 VRRP概念原理报文格式 OS…...

解锁数据宝藏:高效查找算法揭秘

代码下载链接&#xff1a;https://gitee.com/flying-wolf-loves-learning/data-structure.git 目录 一、查找的原理 1.1 查找概念 1.2 查找方法 1.3平均查找长度 1.4顺序表的查找 1.5 顺序表的查找算法及分析 1.6 折半查找算法及分析 1.7 分块查找算法及分析 1.8 总结…...

利用EasyCVR视频智能监控技术,构建智慧化考场监管体系

随着科技的进步&#xff0c;视频监控在各个领域的应用越来越广泛&#xff0c;其中在考场中的应用尤为显著。视频监控不仅能够提高考场的监管水平&#xff0c;确保考试的公平、公正和公开&#xff0c;还能有效预防和打击作弊行为&#xff0c;为考生营造一个良好的考试环境。 传…...

深度解析:速卖通618风控下自养号测评的技术要点

速卖通每年的618大促活动平台的风控都会做升级&#xff0c;那相对的测评技术也需要进行相应的做升级&#xff0c;速卖通618风控升级后&#xff0c;自养号测评需要注意以下技术问题&#xff0c;以确保测评 的稳定性和安全性&#xff1a; 一、物理环境 1. 硬件参数伪装&#x…...

国产算力——沐曦GPU性能及应用

沐曦集成电路&#xff08;上海&#xff09;有限公司&#xff08;简称“沐曦”&#xff09;成立于2020年9月&#xff0c;专注于为异构计算提供全栈GPU芯片及解决方案&#xff0c;满足数据中心对“高性能”、“高能效”及“高通用性”的算力需求。 产品系列 沐曦构建了全栈高性…...