雪花算法(Snowflake Algorithm)
雪花算法(Snowflake Algorithm)是一种分布式唯一ID生成算法,主要用于生成全球唯一的ID,广泛应用于分布式系统中,例如在数据库中作为主键。这个算法最初由Twitter提出,并且被广泛使用在很多大规模系统中。有以下特性:
唯一性: 确保生成的每一个ID都是全球唯一的,避免冲突。
时间有序性: 根据生成ID的时间戳,使得ID按时间顺序排列,方便进行时间排序和处理。
高效性: 在高并发环境下能够快速生成ID,通常在每毫秒内能够生成多个ID。
雪花算法的核心思想是将ID分解成几个部分,以确保生成的ID具有唯一性,同时又能保持一定的顺序性。它的ID结构一般包括以下几个部分:
时间戳(Timestamp): 用于表示当前时间的毫秒数。通常,时间戳占用最前面的一部分位数,这样可以保证ID在时间上有序。
数据中心ID(Data Center ID): 用于标识不同的数据中心,确保在不同的数据中心生成的ID不会冲突。
工作机器ID(Worker ID): 用于标识同一数据中心下的不同工作机器,确保同一数据中心内的不同机器生成的ID也不会冲突。
序列号(Sequence Number): 用于在同一毫秒内生成多个ID,以保证同一时间戳下生成的ID仍然唯一。
雪花算法通常生成的ID长度是64位,具体结构可能有所不同,但一个常见的结构是:
1位符号位(通常固定为0)
41位时间戳(表示毫秒数,一般支持约69年的时间范围)
10位数据中心ID和工作机器ID(分为5位数据中心ID和5位工作机器ID,支持最多1024个数据中心,每个数据中心支持最多1024台机器)
12位序列号(支持每毫秒生成4096个不同的ID)
这种设计可以保证生成的ID是全局唯一的,同时还能保持一定的顺序性,适用于高并发的分布式系统。
工作原理
生成ID时,算法会获取当前时间戳。
结合数据中心ID、工作机器ID以及序列号生成唯一ID。
如果在同一毫秒内生成多个ID,算法会增加序列号以确保唯一性。
在时间戳变化时,算法会重置序列号,并更新ID的时间戳部分。
优点有:
全局唯一性:能够在分布式系统中确保生成的ID全局唯一。
趋势递增性:生成的ID基本呈趋势递增,有利于数据库性能优化。
灵活性:可以根据业务特性灵活分配bit位。
高性能:不依赖数据库等第三方系统,以服务方式部署,生成ID的性能高。
缺陷有:
时钟回退问题:雪花算法依赖于系统时间戳来生成唯一 ID。如果系统时间被设置回过去,可能会导致生成重复的 ID 或者抛出异常。这是使用雪花算法时需要特别注意的问题,因为时钟回退会直接影响到 ID 的唯一性和生成稳定性。
时间戳依赖:雪花算法的 ID 生成是基于系统时间戳的。如果系统时间出现问题(如时钟漂移或系统时间错误),则会影响 ID 的生成。这使得系统时间的准确性和稳定性变得至关重要。
数据中心 ID 和工作机器 ID 的管理:需要合理分配和管理数据中心 ID 和工作机器 ID,以避免冲突。在大规模分布式系统中,如何分配和协调这些 ID 是一个挑战,错误的配置可能导致 ID 冲突或生成不一致。
高并发处理复杂性:在高并发场景下,雪花算法通过序列号来处理生成的 ID,但在极高负载情况下,仍然需要精细管理性能和同步问题。高并发可能导致性能瓶颈或增加实现的复杂性。
代码实现
public class SnowflakeIdGenerator {// 起始时间戳 (2020-01-01 00:00:00)private static final long START_TIMESTAMP = 1577836800000L;// 工作机器 ID 位数private static final long WORKER_ID_BITS = 5L;// 数据中心 ID 位数private static final long DATA_CENTER_ID_BITS = 5L;// 序列号位数private static final long SEQUENCE_BITS = 12L;// 工作机器 ID 最大值private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);// 数据中心 ID 最大值private static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);// 序列号最大值private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);// 工作机器 ID 和数据中心 IDprivate final long workerId;private final long dataCenterId;// 序列号和上次时间戳private long sequence = 0L;private long lastTimestamp = -1L;/*** 构造函数,初始化工作机器 ID 和数据中心 ID。* * @param workerId 工作机器 ID* @param dataCenterId 数据中心 ID* @throws IllegalArgumentException 如果 workerId 或 dataCenterId 超出范围*/public SnowflakeIdGenerator(long workerId, long dataCenterId) {if (workerId > MAX_WORKER_ID || workerId < 0) {throw new IllegalArgumentException("Worker ID out of range");}if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {throw new IllegalArgumentException("Data Center ID out of range");}this.workerId = workerId;this.dataCenterId = dataCenterId;}/*** 生成下一个唯一的 ID。* * @return 生成的 ID*/public synchronized long nextId() {long timestamp = currentTimestamp();// 检查时钟是否回退if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards. Refusing to generate id");}// 当前时间戳与上次时间戳相同,处理序列号溢出if (timestamp == lastTimestamp) {sequence = (sequence + 1) & SEQUENCE_MASK;if (sequence == 0) {timestamp = waitNextMillis(lastTimestamp);}} else {// 当前时间戳不同,重置序列号sequence = 0L;}lastTimestamp = timestamp;// 生成唯一 IDreturn ((timestamp - START_TIMESTAMP) << (WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)) |(dataCenterId << (WORKER_ID_BITS + SEQUENCE_BITS)) |(workerId << SEQUENCE_BITS) |sequence;}/*** 等待直到下一个毫秒。* * @param lastTimestamp 上次生成 ID 的时间戳* @return 当前时间戳*/private long waitNextMillis(long lastTimestamp) {long timestamp = currentTimestamp();while (timestamp <= lastTimestamp) {timestamp = currentTimestamp();}return timestamp;}/*** 获取当前时间戳。* * @return 当前时间戳(毫秒)*/private long currentTimestamp() {return System.currentTimeMillis();}/*** 测试生成 ID。* * @param args 命令行参数*/public static void main(String[] args) {SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);for (int i = 0; i < 10; i++) {System.out.println(idGenerator.nextId());}}
}
相关文章:
雪花算法(Snowflake Algorithm)
雪花算法(Snowflake Algorithm)是一种分布式唯一ID生成算法,主要用于生成全球唯一的ID,广泛应用于分布式系统中,例如在数据库中作为主键。这个算法最初由Twitter提出,并且被广泛使用在很多大规模系统中。有…...
〖任务1〗ROS2 jazzy Linux Mint 22 安装教程
前言: 本教程在Linux系统上使用。 目录 一、linux安装二、linux VPN安装三、linux anaconda安装(可选)四、linux ROS2 安装五、rosdep init/update 解决方法六、安装GUI 一、linux安装 移动硬盘安装linux:[LinuxToGo教程]把ubunt…...
图像增强:使用周围像素填充掩码区域
制作图像需要填充的掩码区域,对需要填充的位置的mask赋值非0,不需要填充赋值为0使用cv2.inpaint对图像掩码mask中非0元素位置的图像像素进行修复。从而实现使用周围像素填充掩码区域cv2.inpaint 是 OpenCV 库中的一个函数,用于图像修复(inpainting),即填充图像中的损坏区…...
给虚拟机Ubuntu扩展硬盘且不丢数据
1.Ubuntu关机状态下先扩展,如扩展20GB 2.进入ubuntu,切换root登录,必须是root全选,否则启动不了分区工具gparted 将新的20GB创建好后,选择ext4,primary; 3.永久挂载 我的主目录在/并挂载到/dev/sda1 从图…...
Oracle(41)如何使用PL/SQL批量处理数据?
在PL/SQL中,批量处理数据是一种高效的方法,可以在数据库中处理大量数据,而无需逐行操作。批量处理数据的关键技术包括: PL/SQL表(索引表):在内存中存储数据以进行批量操作。FORALL语句…...
JavaEE 第2节 线程安全知识铺垫1
目录 一、通过jconsole.exe查看线程状态的方法 二、Thread类的几种常见属性 三、线程状态 一、通过jconsole.exe查看线程状态的方法 通过jconsole查看线程状态非常实用的方式 只要你安装了jdk,大致按照这个目录就可以找到这个可执行程序: 然后双击这…...
LeetCode Hot100 零钱兑换
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。 示…...
微信小程序接口实现语音转文字
一、效果展示 我们有一个按钮,点击“开始录音”按钮,此时按钮变成“停止录音”并开始计时,点击停止录音后,界面上即可展示返回的文字 二、代码实现 完整代码实现见github 1.小程序端代码 // index.js const recorderManager…...
[Spark Streaming] 读取 Kafka 消息, 插入到 MySQL
以下是一个简单的使用 Spark Streaming 读取 Kafka 消息、统计数据后插入到 MySQL 中的 Scala 代码示例: import org.apache.spark.SparkConf import org.apache.spark.streaming.{Seconds, StreamingContext} import org.apache.spark.streaming.kafka.KafkaUtils…...
精选3款国内wordpress 主题,建站首选
WordPress作为一款功能强大且易于使用的建站平台,已经成为了许多企业和个人搭建网站的首选。为了帮助大家更好地选择适合自己的WordPress主题,小编将为大家推荐三款国内优秀的WordPress主题:子比主题、OneNav主题和RiTheme主题。 1.子比主题…...
JavaScript之 Uint8Array 类型数组(solana pda场景中的大小端)
文章目录 JavaScript之 Uint8Array 类型数组numberToUint8Array 数字转换为Uint8Array为什么要把数字转换为Uint8Array数字转换为Uint8Array的大小端问题solana pda场景中的大小端JavaScript之 Uint8Array 类型数组 Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容…...
《Windows API每日一练》24.1 WinSock简介
本节将逐一介绍WinSock的主要特性和组件,套接字、WinSock动态库的使用。 本节必须掌握的知识点: Windows Socket接口简介 Windows Socket接口的使用 第178练:网络时间校验 24.1.1 Windows Socket接口简介 ■以下是WinSock的主要特性和组件…...
openwrt编译Dockerfile
一、Dockerfile FROM ubuntu:20.04ENV TZAsia/ShanghaiRUN apt-get update && \apt-get install -y --no-install-recommends tzdata && \ln -fs /usr/share/zoneinfo/$TZ /etc/localtime && \dpkg-reconfigure --frontend noninteractive tzdata &am…...
【C语言】分支与循环(循环篇)——结尾猜数字游戏实现
前言 C语言是一种结构化的计算机语言,这里指的通常是顺序结构、选择结构、循环结构,掌握这三种结构之后我们就可以解决大多数问题。 分支结构可以使用if、switch来实现,而循环可以使用for、while、do while来实现。 1. while循环 C语言中…...
【数据结构】链表篇
文章目录 1.链表的概念以及结构2.链表的分类2.1 单向或者双向2.2 带头或者不带头2.3 循环或者不循环2.4 无头单向非循环链表和带头双向循环链表 3.单链表的实现3.1 准备工作3.2 节点的创建3.3 单链表的释放3.4 打印链表3.5 单链表的尾插3.6 单链表的尾删3.7 单链表头删3.8 单链…...
Python SciPy介绍
在数据科学和工程领域,Python已经成为了一个不可或缺的工具,这主要得益于其强大的库和框架支持。其中,SciPy库作为Python科学计算的核心库之一,为研究人员、工程师和数据分析师提供了大量高效的算法和数学工具。本文将带您深入了解…...
docker镜像源
1、直接在服务器上创建这个文件,将镜像源配置在里面 /etc/docker/daemon.json {"registry-mirrors": ["https://do.nark.eu.org","https://dc.j8.work","https://docker.m.daocloud.io","https://dockerproxy.com&qu…...
【clion】clion打开文件目录卡死问题
巨卡,几乎无法打开,据说是fsnotifier64.exe 被限制了。删除 火绒就好了。 关闭windows defender 官方:关闭 Windows 安全中心中的Defender 防病毒保护 此时,删除火绒: 界面变这样了:...
[CR]厚云填补_GridFormer
GridFormer: Residual Dense Transformer with Grid Structure for Image Restoration in Adverse Weather Conditions Abstract 恶劣天气条件下的图像恢复是计算机视觉中的一个难点。在本文中,我们提出了一种新的基于变压器的框架GridFormer,它可以作为…...
PostgreSQL数据库内核(二):通过initdb传递guc参数
目录 增加guc参数 initdb参数传递 pg_ctl参数传递 参数验证 新增guc参数pg_test_parameter,支持从initdb和pg_ctl命令中传递/覆盖参数,使用场景是TDE透明加密指定算法或者某些定制化需求。 增加guc参数 pg源码是这样描述guc参数的:它是全局…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
