深入了解Snowflake雪花算法:分布式唯一ID生成器

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

深入了解Snowflake算法:分布式唯一ID生成器

  • 前言
  • Snowflake算法原理
  • Snowflake算法的优点
  • Snowflake算法Java代码实现
  • Snowflake算法使用注意事项
  • 结语

前言

在分布式系统中,生成唯一ID是一项关键的任务。Snowflake算法是Twitter公司开发的一种分布式唯一ID生成算法,通过对时间、机器ID和序列号的合理组合,保证在分布式环境中生成唯一的64位ID。本文将深入解析Snowflake算法的原理,并附带Java代码示例。

Snowflake算法原理

Snowflake算法的生成规则如下:

  • 固定值(1位):占用1bit,其值始终是0,可看做是符号位不使用。

  • 时间戳部分(41位): 用来记录生成ID的时间戳,精确到毫秒。这意味着Snowflake可以使用69年。

  • 机器ID部分(10位): 用来标识机器,可以部署在2^10台机器上。

  • 序列号部分(12位): 用来标识同一毫秒内产生的不同ID,支持同一机器同一毫秒内生成4096个ID。

雪花结构如下图
在这里插入图片描述

Snowflake算法的优点

Snowflake算法的优点:

  • 唯一性: Snowflake算法生成的ID在分布式环境中具有唯一性,通过合理的配置,可以避免ID冲突问题。

  • 趋势递增: 由于Snowflake算法使用时间戳作为基础,生成的ID呈趋势递增,便于数据库索引,有利于提高数据库性能。

  • 高性能: Snowflake算法的实现简单,性能较高,适用于大规模分布式系统。

  • 分布式: Snowflake算法天生支持分布式部署,适用于需要在多个节点生成唯一ID的场景。

  • 可定制性: Snowflake算法的位数分配是可以根据实际需求进行调整的,可以根据业务规模进行定制。

Snowflake算法的缺点:

  • 依赖系统时钟: Snowflake算法的唯一性依赖于系统时钟的单调递增,如果系统时钟回拨,可能导致生成的ID不唯一。

  • 时钟回拨问题: 如果系统发生时钟回拨,可能会导致生成的ID不是趋势递增的,影响数据库性能。

  • 有一定的时延: Snowflake算法生成ID时需要依赖当前时间戳,可能会有一定的时延。

  • 不适用于短时间内需要大量生成ID的场景: 在短时间内需要大量生成ID的场景下,可能会出现ID的序列号用尽的情况。

  • 对机器时钟要求较高: 如果机器之间的时钟差异较大,可能会导致生成的ID不唯一。

在使用Snowflake算法时,需要根据具体业务场景综合考虑其优缺点,确保在分布式环境中生成唯一且趋势递增的ID。

Snowflake算法Java代码实现

以下是一个简单的Java实现示例:

public class SnowflakeIdGenerator {private final long twepoch = 1288834974657L; // 起始时间戳,可以根据实际情况调整private final long workerIdBits = 5L;private final long dataCenterIdBits = 5L;private final long maxWorkerId = -1L ^ (-1L << workerIdBits);private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);private final long sequenceBits = 12L;private final long workerIdShift = sequenceBits;private final long dataCenterIdShift = sequenceBits + workerIdBits;private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;private final long sequenceMask = -1L ^ (-1L << sequenceBits);private long workerId;private long dataCenterId;private long sequence = 0L;private long lastTimestamp = -1L;public SnowflakeIdGenerator(long workerId, long dataCenterId) {if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException("Worker ID can't be greater than " + maxWorkerId + " or less than 0");}if (dataCenterId > maxDataCenterId || dataCenterId < 0) {throw new IllegalArgumentException("Datacenter ID can't be greater than " + maxDataCenterId + " or less than 0");}this.workerId = workerId;this.dataCenterId = dataCenterId;}public synchronized long nextId() {long timestamp = timeGen();if (timestamp < 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 = 0L;}lastTimestamp = timestamp;return ((timestamp - twepoch) << timestampLeftShift) |(dataCenterId << dataCenterIdShift) |(workerId << workerIdShift) |sequence;}private long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}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);}}
}

Snowflake算法使用注意事项

时间回拨问题

如果系统时间发生回拨,可能会导致生成的ID不唯一。因此,在使用Snowflake算法时要确保系统时间是单调递增的。

机器ID和数据中心ID:

在部署时,要确保不同的机器和数据中心分配不同的ID,避免产生重复的ID。

性能

Snowflake算法依赖于系统时钟,如果系统时钟频繁变动,可能会影响性能。

结语

Snowflake算法是一种简单而高效的分布式唯一ID生成方案,广泛应用于分布式系统中。通过合理配置机器ID和数据中心ID,以及注意时间回拨问题,我们可以确保Snowflake算法生成的ID在分布式环境中的唯一性。在实际应用中,可以根据业务需求进行适当的调整和定制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/604087.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go 切片长度与容量的区别

切片的声明 切片可以看成是数组的引用&#xff08;实际上切片的底层数据结构确实是数组&#xff09;。在 Go 中&#xff0c;每个数组的大小是固定的&#xff0c;不能随意改变大小&#xff0c;切片可以为数组提供动态增长和缩小的需求&#xff0c;但其本身并不存储任何数据。 …

安全测试之SSRF请求伪造

前言 SSRF漏洞是一种在未能获取服务器权限时&#xff0c;利用服务器漏洞&#xff0c;由攻击者构造请求&#xff0c;服务器端发起请求的安全漏洞&#xff0c;攻击者可以利用该漏洞诱使服务器端应用程序向攻击者选择的任意域发出HTTP请求。 很多Web应用都提供了从其他的服务器上…

Stable Diffusion 系列教程 - 6 Dreambooth及训练

Stable-Diffusion、Imagen等文生图大模型已经具备了强大的生成能力&#xff0c;假设我们的Prompt为 [Cyberpunk Style]&#xff0c;SD或许能很快画出赛博朋克风格的一幅画。但你作为一个不知名的人&#xff0c;不能奢求SD在训练的时候把你自己想要的风格也加进去吧&#xff1f;…

『C++成长记』日期类的实现

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;C &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、日期类的实现 &#x1f4d2;1.1日期类功能 &#x1f4d2;1.2拷贝日期 &#…

自动驾驶代客泊车PAVP功能规范

目录 1. 版本记录......................................................................................... 4 2. 引言................................................................................................ 5 2.1 目的/范围...............…

2023的线上事故复盘总结(OOM,数据库崩溃)持续更新中~

项目场景&#xff1a; 智慧门禁系统&#xff0c;公司研制的一个saas系统&#xff0c;基于Springcloud框架&#xff0c;主要是面向高校对老师学生的通行方式做统一的管理&#xff0c;可通过卡、码、脸等多种方式进出&#xff0c;可实现不同人员进出不同的场所&#xff0c;例如宿…

使用ChatGPT生成i项目需求文档模板

前言 我们在工作中需要编写的技术文档有多种形式&#xff0c;包括Word、Excel、PDF及一些在线形式。我们可以借助ChatGPT生成文本&#xff0c;然而&#xff0c;它不能直接生成Word、Excel、PDF等格式的文档。因此&#xff0c;我们需要利用其他工具来帮助我们生成一些模板&…

三、计算机理论-关系数据库-数据库的完整性与安全性,事务管理、并发控制、数据库的备份与恢复

数据库完整性 完整性是为了防止合法用户在使用数据库时向数据库中加入不符合语义的数据 实体完整性 实体完整性约束时通过主码的定义来实现的&#xff0c;使用PRIMARY KEY来定义&#xff0c;对于单个属性的主码可以使用列级完整性约束&#xff0c;若主码是一个属性组&#xff…

golang如何生成csv文件

在Go语言中&#xff0c;可以使用标准库中的"encoding/csv"包来生成CSV文件。下面是一个简单的示例代码&#xff0c;演示如何使用Go生成CSV文件&#xff1a; package mainimport ("encoding/csv""os" )func main() {// 创建一个新的CSV文件file,…

EtherCAT主站SOEM -- 14 --Qt-Soem通过界面采集从站IO进行显示

EtherCAT主站SOEM -- 14 --Qt-Soem通过界面采集从站IO进行显示 一 mainwindow.c 文件函数:1.1 自定义PDO配置1.2 主站初始化二 motrorcontrol.c 文件三 allvalue.h 文件该文档修改记录:总结一 mainwindow.c 文件函数: 1.1 自定义PDO配置 int IO_setup(uint16 slave) {int

YoloV7使用detect.py检测,结果图片不显示框

detect.py里画框部分默认是屏蔽的&#xff0c;需要自己打开。下图红框里屏蔽部分打开后&#xff0c;就显示框了。

QT上位机开发(日志调试)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 程序开发中有很多的调试方法&#xff0c;比如说IDE调试&#xff0c;也就是设置断点、查看变量等等&#xff1b;比如说日志调试&#xff1b;比如说c…

PDF控件Spire.PDF for .NET【安全】演示:获取并验证 PDF 中的数字签名

在 PDF 中创建数字签名广泛用于保护 PDF 文件。因此&#xff0c;当您查看一些带有数字签名的PDF文件时&#xff0c;需要获取并验证数字签名。本文向您展示了一种通过使用Spire.PDF和 C# 代码来获取和验证 PDF 中的数字签名的解决方案。 Spire.PDF for .NET 是一款独立 PDF 控件…

【Linux】常用的基本命令指令①

前言&#xff1a;从今天开始&#xff0c;我们逐步的学习Linux中的内容&#xff0c;和一些网络的基本概念&#xff0c;各位一起努力呐&#xff01; &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:数据结构 &#x1f448; &#x1f4af;代码…

CLIP is Also an Efficient Segmenter

表1 复现结果–Seed&#xff1a;70.7245673447014&#xff0c;dCRF&#xff1a;74.85437742935268 误差小于0.5个点&#xff0c;可以接受 表4 复现结果–训练300轮&#xff0c;Val&#xff1a;58.76741354153312&#xff0c;Test&#xff1a;59.18210 感想 VOC全部复现完成&…

基于SpringBoot的校园外卖服务系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的校园外卖服务系统,java…

小白入门基础 - tomcat

一&#xff1a;前言 Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP 程序的首选。对于一个初学者来说&#xff0c;可以这样认为&#x…

xxxView

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;…

【INTEL(ALTERA)】生产中使用多个目标设备,如何满足外部内存接口Intel Agilex® 7偏移匹配准则?

说明 对于外部内存接口Intel Agilex 7使用的引脚&#xff0c;不同的引脚兼容设备可能会有不同的封装延迟。如果您遵循《外部内存接口用户指南》中的“偏移匹配指南”部分所述的要求&#xff0c;您可能会发现无法同时满足多个器件的要求。用户指南仅适用于您计划在开发阶段使用…

【SpringBoot+dubbo+zk】实现服务之间rpc通信

0)前置准备&#xff0c;我们使用zk作为注册中心&#xff0c;先启动zk&#xff0c;也就是2181端口。 1)父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http…