【分布式】雪花算法学习笔记
雪花算法学习笔记
来源
https://pdai.tech/md/algorithm/alg-domain-id-snowflake.html
概述
- 雪花算法是推特开源的分布式ID生成算法,以划分命名空间的方式将64位分割成多个部分,每一个部分代表不同的含义,这种就是将64位划分成不同的段,每一个段代表不同的涵义
- 时间戳 + 机器ID + 序列数
结构
- 第一位占用一个bit 值始终为0,可以看作符号位不可使用
- 第二位开始的41位是时间戳,41bit可以表示2^41个数字,每一个数字代表s,那么雪花算法表示的时间年限是69年时间
- 中间的10bit将其中5bit分给IDC(互联网数据中心),5bit给工作机器,这样就可以表示32个IDC,然后每一个IDC有32台机器
- 最后12bit是自增序列,可以表示2^12=4096
这样划分相当于在一毫秒的一个数据中心的一台机器上可以产生4096个有序的不重复的ID

package SnowFlake;/*** Twitter_Snowflake<br>* SnowFlake的结构如下(每部分用-分开):<br>* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>* 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>* 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)* 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>* 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>* 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>* 加起来刚好64位,为一个Long型。<br>* SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。*/
public class SnowflakeDistributeId {// ==============================Fields===========================================/*** 开始时间截 (2015-01-01)*/private final long twepoch = 1420041600000L;/*** 机器id所占的位数*/private final long workerIdBits = 5L;/*** 数据标识id所占的位数*/private final long datacenterIdBits = 5L;/*** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)*/private final long maxWorkerId = -1L ^ (-1L << workerIdBits);/*** 支持的最大数据标识id,结果是31*/private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);/*** 序列在id中占的位数*/private final long sequenceBits = 12L;/*** 机器ID向左移12位*/private final long workerIdShift = sequenceBits;/*** 数据标识id向左移17位(12+5)*/private final long datacenterIdShift = sequenceBits + workerIdBits;/*** 时间截向左移22位(5+5+12)*/private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;/*** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)*/private final long sequenceMask = -1L ^ (-1L << sequenceBits);/*** 工作机器ID(0~31)*/private long workerId;/*** 数据中心ID(0~31)*/private long datacenterId;/*** 毫秒内序列(0~4095)*/private long sequence = 0L;/*** 上次生成ID的时间截*/private long lastTimestamp = -1L;//==============================Constructors=====================================/*** 构造函数** @param workerId 工作ID (0~31)* @param datacenterId 数据中心ID (0~31)*/public SnowflakeDistributeId(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;}// ==============================Methods==========================================/*** 获得下一个ID (该方法是线程安全的)** @return SnowflakeId*/public synchronized long nextId() {long timestamp = timeGen();//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常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;}//上次生成ID的时间截lastTimestamp = timestamp;//移位并通过或运算拼到一起组成64位的IDreturn ((timestamp - twepoch) << timestampLeftShift) //| (datacenterId << datacenterIdShift) //| (workerId << workerIdShift) //| sequence;}/*** 阻塞到下一个毫秒,直到获得新的时间戳** @param lastTimestamp 上次生成ID的时间截* @return 当前时间戳*/protected long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}/*** 返回以毫秒为单位的当前时间** @return 当前时间(毫秒)*/protected long timeGen() {return System.currentTimeMillis();}
}
总结
- 雪花算法生成的ID是趋势递增
- 不依赖数据库等第三方系统
- 依赖机器始终,如果机器时钟回拨,会导致发号重复或者服务处于不可用状态,如果恰巧回退前生成过一些ID,但是时间回退之后,生成的ID就有可能重复
相关文章:
【分布式】雪花算法学习笔记
雪花算法学习笔记 来源 https://pdai.tech/md/algorithm/alg-domain-id-snowflake.html概述 雪花算法是推特开源的分布式ID生成算法,以划分命名空间的方式将64位分割成多个部分,每一个部分代表不同的含义,这种就是将64位划分成不同的段&…...
6.函数表达式 - JS
函数表达式 function (someArgs) { someStatements } function name(someArgs) { someStatements } (someArgs) > { someStatements }函数表达式就是要,在一个表达式中定义一个函数;箭头函数也是一个简洁的函数表达式;执行完函数表达式&a…...
【RK3288 Android10 C30 支持sim卡拔掉不弹窗,及热插拔】
文章目录 【RK3288 Android10 C30 支持sim卡拔掉不弹窗,及热插拔】需求方案patchframework【RK3288 Android10 C30 支持sim卡拔掉不弹窗,及热插拔】 需求 由于3288 硬件上的sim卡座不支持热插拔,是没有顶针来识别sim卡是否被拔掉的。所以在sim被拔掉或者松动的时候,会弹窗…...
python生成docx文件
使用python自动生成一张想要的docx文件 在这其中有指纹和公司盖章 from PIL import Image from docx import Document from docx.oxml.ns import qn from docx.shared import Pt, Inches, Cm from docx.enum.text import WD_PARAGRAPH_ALIGNMENT from xlsxtpl.writerx import …...
网络异常案例四_IP异常
问题现象 终端设备离线,现场根据设备ip,ping不通。查看路由器。 同一个路由器显示的终端设备(走同一个wifi模块接入),包含不同网段的ip。 现场是基于三层的无线漫游,多个路由器wifi配置了相同的ssid信息&a…...
Hack The Box-Challenges-Misc-M0rsarchive
解压压缩包,里面是一张图片和一个新的zip文件 图片放大后的图案是----. 考虑到为莫斯密码,将其解密 密码为9,继续解压缩包 又是一张莫斯密码图加压缩包,写一段脚本去解密图片中的莫斯密码,并自动解压缩包 import re i…...
验证码倒计时:用户界面的小细节,大智慧
欢迎来到我的博客,代码的世界里,每一行都是一个故事 验证码倒计时:用户界面的小细节,大智慧 前言为什么需要验证码倒计时防止滥用:用户心理: 设计考量可见性:友好性:适应性ÿ…...
Web后端:CSRF攻击及应对方法
CSRF攻击是开发Web后端时需要重点解决的问题。 那么什么是CSRF攻击呢? CSRF跨站点请求伪造(Cross—Site Request Forgery),其主要利用的是Cookie的一个弱点,就是Cookie 最初被设计成了允许在第三方网站发起的请求中携带: 关于Co…...
【手写数据库toadb】toadb表对象访问操作,存储管理抽象层软件架构设计思想应用
21 表文件访问秘密 专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便…...
SpringBoot使用Rabbit详解含完整代码
点击下载《SpringBoot使用Rabbit详解含完整代码》 1. 摘要 本文将详细介绍如何在Spring Boot应用程序中集成和使用RabbitMQ消息队列。RabbitMQ是一个开源的消息代理和队列服务器,用于通过轻量级和可靠的消息在应用程序或系统之间进行异步通信。本文将通过步骤说明…...
深度学习本科课程 实验3 网络优化
一、在多分类任务实验中实现momentum、rmsprop、adam优化器 1.1 任务内容 在手动实现多分类的任务中手动实现三种优化算法,并补全Adam中计算部分的内容在torch.nn实现多分类的任务中使用torch.nn实现各种优化器,并对比其效果 1.2 任务思路及代码 imp…...
Eclipse 安装使用ABAPGit
Eclipse->Help->Install New software 添加地址 https://eclipse.abapgit.org/updatesite/ 安装完成打开 选择abapGit repositories,先添加仓库 点下图添加自己仓库 如图添加仓库地址 添加完仓库后,点击我的仓库 右键选中行,可以进行push和pu…...
std::mutex std::recursive_mutex std::shared_mutex
std::mutex C11。最简单的互斥锁,1个线程内,不支持重复加锁。 std::lock_guard<std::mutex> lock(mutex) std::recursive_mutex C11。可以替代st::mutex,但性能会下降。1个线程内,支持重复加锁(可重入&#x…...
vscode的vetur文档格式化失效
如果vscode安装了vetur插件之后,shiftAltF又无法格式化vue文件代码。 解决办法:打开文件 ---> 首选项 ---> 设置,搜索 vetur.format.defaultFormatter.html后将prettier替换勾选为js-beautify-html 注:设置下划线了并可以在…...
idea 快捷键ctrl+shift+f失效的解决方案
文章目录 搜狗输入法快捷键冲突微软输入法快捷键冲突 idea的快捷键ctrlshiftf按了没反应,理论上是快捷键冲突了,检查搜狗输入法和微软输入法快捷键。 搜狗输入法快捷键冲突 不需要简繁切换的快捷键,可以关闭它,或修改快捷键。 微…...
C++面试:数据库的连接池管理
目录 基本概念 工作原理 核心组件 实现机制 优点 缺点 实践建议 实例 场景描述 解决方案:引入数据库连接池 配置数据库连接池 使用连接池 监控和调优 效果 结论 数据库连接池管理是一个在软件开发中常见的优化策略,特别是在需要频繁访问数…...
React Hook之钩子调用规则(不在循环、条件判断或者嵌套函数中调用)
文章目录 React Hook之钩子调用规则(不在循环、条件判断或者嵌套函数中调用)错误使用案例案例具体解决方法 React Hook之钩子调用规则(不在循环、条件判断或者嵌套函数中调用) hooks使用规则 只能在函数最外层调用 Hook。不要在…...
深入理解TCP网络协议(3)
目录 1.前言 2.流量控制 2.阻塞控制 3.延时应答 4.捎带应答 5.面向字节流 6.缓冲区 7.粘包问题 8.TCP异常情况 9.小结 1.前言 在前面的博客中,我们重点介绍了TCP协议的一些属性,有连接属性的三次握手和四次挥手,还有保证数据安全的重传机制和确认应答,还有为了提高效率…...
JavaScript实现归并排序及vscode输出乱码解决
思路 归并排序思路:11.6 归并排序 - Hello 算法 总体上来讲就是 递归分解 归并排序 代码如下↓ 代码 //归并排序 function merge(left, right){console.log(flag);console.log(left);console.log(right);let result new Array();let il 0, ir 0;//左右两个数…...
Redis面试题40
人工智能如何影响医疗保健行业? 答:人工智能对医疗保健行业产生了深远的影响,为医疗保健提供了更高效、准确和个性化的服务。以下是一些人工智能在医疗保健领域的应用示例: 疾病诊断:人工智能可以利用机器学习和深度学…...
AgentCPM深度研报助手企业级部署架构设计:高并发下的性能与成本优化
AgentCPM深度研报助手企业级部署架构设计:高并发下的性能与成本优化 最近和几个做金融科技的朋友聊天,他们都在头疼一件事:公司内部的分析师、研究员越来越多地依赖AI来辅助撰写行业研报,但现有的AI服务要么太贵,要么…...
Spring Data事务管理与多租户架构:企业级数据隔离终极指南
Spring Data事务管理与多租户架构:企业级数据隔离终极指南 【免费下载链接】spring-data-examples Spring Data Example Projects 项目地址: https://gitcode.com/gh_mirrors/sp/spring-data-examples Spring Data事务管理与多租户架构是企业级应用开发中的两…...
Unity零基础入门指南:借助快马AI生成你的第一个可交互3D场景
Unity零基础入门指南:借助快马AI生成你的第一个可交互3D场景 作为一个刚接触Unity的新手,我完全理解那种面对空白项目时的迷茫感。好在最近发现了InsCode(快马)平台,它让我这个编程小白也能快速创建出像模像样的3D交互场景。下面我就分享一下…...
终极图像纹理合成工具:GIMP Resynthesizer 完整使用指南
终极图像纹理合成工具:GIMP Resynthesizer 完整使用指南 【免费下载链接】resynthesizer Suite of gimp plugins for texture synthesis 项目地址: https://gitcode.com/gh_mirrors/re/resynthesizer GIMP Resynthesizer 是一套功能强大的 GIMP 纹理合成插件…...
Phi-4-mini-reasoning效果对比:与Qwen-Math、DeepSeek-Math在逻辑题上的表现差异
Phi-4-mini-reasoning效果对比:与Qwen-Math、DeepSeek-Math在逻辑题上的表现差异 1. 模型介绍与测试背景 1.1 参测模型概览 本次对比测试聚焦三个专门针对数学和逻辑推理优化的模型: Phi-4-mini-reasoning:微软推出的轻量级推理专用模型&…...
如何高效管理百度网盘文件:自动化批量转存与分享的完整指南
如何高效管理百度网盘文件:自动化批量转存与分享的完整指南 【免费下载链接】BaiduPanFilesTransfers 百度网盘批量转存、分享和检测工具 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduPanFilesTransfers 在数字资源日益丰富的今天,百度网盘…...
卷积神经网络(CNN)原理可视化解释:Phi-4-mini-reasoning担任AI讲师
卷积神经网络(CNN)原理可视化解释:Phi-4-mini-reasoning担任AI讲师 1. 当AI成为你的机器学习导师 想象一下,有位从不疲倦的讲师,能用最生动的比喻解释复杂的算法原理,还能实时生成配套示意图——这就是Ph…...
用STC89C51+ESP8266-01做个宿舍环境监测器,再用App Inventor2做个手机App(保姆级避坑指南)
宿舍环境监测器实战:STC89C51ESP8266与App Inventor 2避坑指南 凌晨三点,室友的鼾声和窗外施工噪音让你辗转难眠。更糟的是,你发现喉咙干涩、头昏脑胀——这间不到20平米的宿舍里,二氧化碳浓度早已超标。作为电子爱好者࿰…...
Wan2.2-I2V-A14B开源镜像实测:xFormers+FlashAttention-2加速推理35%+
Wan2.2-I2V-A14B开源镜像实测:xFormersFlashAttention-2加速推理35% 1. 镜像概述与核心价值 Wan2.2-I2V-A14B是一款专为文生视频任务优化的私有部署镜像,它让高质量视频生成变得触手可及。这个镜像最吸引人的地方在于,它已经为你准备好了所…...
模电设计实践之“音频功率放大器的设计” - 包含OCL主放大器设计、总电路图与框架详解、设计方...
模电设计实践之音频功率放大器的设计(word文档)文档有详细的参数计算过程 其主要内容是: 1、OCL主放大器的设计 2、总电路图、框架图以及单元电路介绍 3、设计方案论证 4、设计及电路参数计算,元器件选择 5、技术指标校验拆开音响…...
