在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。如在美团点评的金融、支付、餐饮、酒店、猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一 ID 来标识一条数据或消息,数据库的自增 ID 显然不能满足需求;特别一点的如订单、骑手、优惠券也都需要有唯一 ID 做标识。此时一个能够生成全局唯一ID 的系统是非常必要的。

Leaf——美团点评分布式ID生成系统

本文主要介绍一些常见的分布式唯一 ID 生成方案。

UUID(通用唯一识别码)

UUID 是 Universally Unique Identifier 的缩写,其目的是为了满足在分布式系统中,各个节点可以独立的生成唯一标识符,不需要依赖一个中心化的服务来分配 ID。相关设计最早在 1980 年代就已经提出,最终 2005 年在 RFC4122 中被完整定义。2024 年最新的 RFC 9562 发布,新增了 3 个新版本的 UUID 生成算法,取代了 RFC4122。

UUID 本身是一个长度为 128bit 的数字,通常用 32 位长度的 16 进制数字表示。因此其理论上的总数为 2^128,约等于 3.4 x 10^38。也就是说如果每纳秒生成一万个 UUID(每秒 10 万亿个),在完全随机版本下,需要 1700 万亿年才能生成完所有的 UUID,妥妥的直到宇宙尽头(宇宙预测寿命为 138 亿年)。

在实际使用中,生成的 UUID 由 32 个字符和 4 个连字符表示,格式为 8-4-4-4-12,我们一般会在生成后将 - 给替换掉 UUID.randomUUID().toString().replaceAll("-","")

RFC 4122 中定义了 5 个版本的 UUID,每个版本的算法不同,应用范围也不同,分别为:

  • Time-based UUID:基于时间的 UUID。通过本机 MAC 地址、时间戳以及a随机数计算出 UUID,格式为 timestamp(60bit)-clock_seq(14bit)-MAC(48bit),另外还有 4bit 的 version 字段和 2 bit 的 variant 字段。因为使用了 MAC 地址,因此理论上绝对唯一,但 UUID 暴露了 MAC 地址,私密性不够好。

  • DCE Security UUID:DCE安全的UUID。和版本一类似,但会将时间戳的前 4 位替换为 POSIX 的 UID 或 GID,实际很少使用。

  • UUID from names(MD5):基于名字的 UUID,通过 MD5(命名空间ID + 名称) 计算出哈希值,该版本可以保证相同输入产生相同输出,但目前 MD5 已经不再安全,容易受到碰撞攻击,现在推荐用 UUIDv5 替代。

  • truly random UUID:完全随机 UUID。根据随机数或者伪随机数生成 UUID,这是使用最广泛的版本,JDK 中实现的就是这个版本。

  • UUID from names(SHA1):UUIDv3 的升级版,通过 SHA1(命名空间ID + 名称) 计算出哈希值,该版本可以保证相同输入产生相同输出,安全性相对较高。

RFC9562 又提出了三个新的版本,分别是:

  • Time-based UUID:对 UUIDv1 的升级,对时间戳进行了重排,将时间戳从高到低位有序排列,从而提高了数据库索引性能。

  • Unix Epoch-based UUID:基于 Unix 时间戳的 UUID,使用当前时间戳(自 1970 年 1 月 1 日以来的毫秒数)作为 UUID 的前 48 位,整体格式为 timestamp(48bit)-version(4bit)-randomA(12bit)-variant(2bit)-randomB(62bit)。 Version7 是专为现代数据库和分布式系统设计的、基于时间的 UUID 格式。它结合了时间戳和高质量的随机数,从而实现了优秀的排序性和唯一性。

    如果开发者使用的语言生态已经支持 Version7,应该优先使用该版本。以笔者熟悉的 Java 和 Golang 为例,JDK 尚不支持 Version7,但已经有 uuid-creator和 java-uuid-generator 开源库支持;Golang 方面 Google 官方的uuid 库已经支持。

  • Custom UUID:自定义 UUID,一种实验性质或供应商特定用途的 UUID,除了 version 和 variant 字段外,其余 122bit 可以自由定义。

下面是使用 Java 和 Golang 生成的 Version4 和 Version7 版本的 UUID 示例:

  • Golang 示例
package mainimport "github.com/google/uuid"func main() {uuidv4 := uuid.New()println("UUIDv4: " + uuidv4.String())uuidv7, _ := uuid.NewV7()println("UUIDv7: " + uuidv7.String())
}

输出结果如下

UUIDv4: 496a53aa-e690-4d8f-bf77-316d294e2f81
UUIDv7: 01989e87-e56c-729b-a341-5faa691e4b24
  • Java 示例

import java.util.UUID;public class UUIDDemo {public static void main(String[] args) {//默认是版本 4,完全随机 IDUUID uuid = UUID.randomUUID();// 替换 -System.out.println(uuid.toString().replaceAll("-",""));}
}

输出结果如下

676a8fee6c1b48028dfc86e2bc35e4fe

数据库自增 ID

一般在设计数据库表时,一定会有一个 AUTO_INCREMENT=1 的 ID 字段,其本身就是一个表范围的全局唯一 ID。但如果数据量达到一定量级,需要分库分表时,生成的 ID 就会重复,此时一般需要设置自增 ID 的起始值和增长步长,比如 MySQL 提供了两个字段进行设置:

  • auto_increment_offset:自增 ID 的起始值,默认是 1。
  • auto_increment_increment:自增 ID 的增长步长,默认是 1。

比如当通过分库分表拆分为三个数据库时,可以设置如下起始值和步长来实现全局自增 ID 唯一:

像数据库的自增 ID、Redis 的 INCRINCRBY 命令,Zookeeper 的 Sequential 节点,都带有自增属性,因此都可以用来实现分布式唯一ID,但这些方案都会对中间件产生依赖。无论是使用的编码复杂度,还是对中间件的高可用性要求,相比其他方案都会有一定的劣势。

雪花算法

Snowflake(雪花算法) 是由 Twitter 提出的分布式唯一 ID 生成方案。其核心思想是将时间戳、机器 ID 和序列号结合在一起,生成一个 64 位的唯一 ID。

雪花算法的 ID 结构如下:

  • 1 个保留位,始终为 0。
  • 41 位时间毫秒时间戳,其可用年限大约为 69 年。
  • 10 位机器 ID,支持 1024 台机器。还可以继续细分, 5 位给 IDC,5 位给工作机器。
  • 12 位序列号,可以表示 2^12 = 4096 个数。因此雪花算法最大支持每毫秒生成 4096 个 ID。

基于以上字段分布,雪花算法可以每毫秒在一个数据中心的一台机器上产生4096个有序的不重复的ID

不过因为是时间戳的原因,雪花算法在生成 ID 时需要考虑时钟回拨的问题。如果系统时间发生回拨,可能会导致生成的 ID 重复。因此在使用雪花算法时,需要确保系统时间的准确性。Twitter 的官方实现并没有对其做明确处理,只是简单的报错,这样会导致分布式ID服务短期内不可用。后续的开源方案,像美团的 Leaf,百度的 UidGenerator 都对其做了优化,这也是比较常用的两个开源库,在实际工程中如果需要,可以在详细调研后进行选型。

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

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

相关文章

飞算JavaAI赋能高吞吐服务器模拟:从0到百万级QPS的“流量洪峰”征服之旅

引言:当“流量洪峰”来袭,如何用低代码驯服高并发? 在数字化时代,从电商平台的“双11”大促到社交网络的突发热点事件,再到金融系统的实时交易高峰,服务器时刻面临着**高吞吐量(High Throughput…

C#数据访问帮助类

一.中文注释using System; using System.Data; using System.Xml; using System.Data.SqlClient; using System.Collections;namespace Microsoft.ApplicationBlocks.Data.Ch {/// <summary>/// SqlServer数据访问帮助类/// </summary>public sealed class SqlHelp…

B站 韩顺平 笔记 (Day 21)

目录 1&#xff08;面向对象高级部分练习题&#xff09; 1.1&#xff08;题1&#xff09; 1.2&#xff08;题2&#xff09; 1.3&#xff08;题3&#xff09; Vehicles接口类&#xff1a; Horse类&#xff1a; Boat类&#xff1a; Plane类&#xff1a; VehiclesFactory…

Linux(十四)——进程管理和计划任务管理

文章目录前言一、程序与进程的关系1.1 程序与进程的定义1.2 父进程与子进程二、查看进程信息2.1 ps 命令&#xff08;重点&#xff09;2.2 动态查看进程信息top命令&#xff08;重点&#xff09;2.3 pgrep命令查询进程信息2.4 pstree命令以树形结构列出进程信息三、进程的启动方…

太阳光模拟器在无人机老化测试中的应用

在无人机技术飞速发展的当下&#xff0c;其户外作业环境复杂多变&#xff0c;长期暴露在阳光照射下&#xff0c;部件老化问题日益凸显&#xff0c;严重影响无人机的性能与寿命。紫创测控Luminbox专注于太阳光模拟器技术创新与精密光学测试系统开发&#xff0c;其涵盖的 LED、卤…

网络原理-TCP_IP

1.UDP&#xff08;即用户数据报协议&#xff09;UDP是一种无连接的传输层协议&#xff0c;提供简单的、不可靠的数据传输服务。它不保证数据包的顺序、可靠性或重复性&#xff0c;但具有低延迟和高效率的特点。UDP协议段格式16位UDP⻓度,表⽰整个数据报(UDP⾸部UDP数据)的最⼤⻓…

GitHub Actions YAML命令使用指南

version: 2 updates:- package-ecosystem: "github-actions"directory: "/"schedule:interval: "weekly"这段代码是 Dependabot 的配置文件&#xff08;通常放在 .github/dependabot.yml 中&#xff09;&#xff0c;它的作用是 自动化管理 GitHu…

决策树算法学习总结

一、经典决策树算法原理 &#xff08;一&#xff09;ID3 算法 核心思想&#xff1a;以 “信息增益” 作为划分属性的选择标准&#xff0c;通过最大化信息增益来提升数据集的 “纯度”。 关键概念 —— 信息增益&#xff1a;指某个属性带来的 “熵减”&#xff08;即纯度提升量&…

内网安全——出网协议端口探测

在实战中难免会遇到各种各样的情况&#xff0c;其中对于目标主机是否出网这是一个十分值得收集的信息&#xff0c;因为完全不出网你就获取不到主机了 端口 Linux 系统 对于 Linux 系统&#xff0c;探测其允许出网的端口&#xff0c;这里使用的是 Linux 的自带命令&#xff0c;所…

C#WPF实战出真汁13--【营业查询】

1、营业查询介绍本模块是最后一个模块&#xff0c;该板块需要的功能有&#xff1a;营业数据列表&#xff0c;查询数据&#xff0c;导出数据&#xff0c;数据统计。2、UI设计布局TabControl 是 WPF 中用于创建多页标签式界面的控件&#xff0c;常用于组织多个子内容区域。每个子…

基于 Java 和 MySQL 的精品课程网站

基于 Java 和 MySQL 的精品课程网站设计与实现一、 毕业设计&#xff08;论文&#xff09;任务书摘要&#xff1a;近年来&#xff0c;教育信息化发展十分迅猛&#xff0c;人们的教育观念、教育手段、学习方法、学习渠道等等都发生了重大的变化。知识性人才也已经日益成为了一个…

全球首款 8K 全景无人机影翎 A1 发布解读:航拍进入“先飞行后取景”时代

全球首款 8K 全景无人机影翎 A1 发布解读&#xff1a;航拍进入“先飞行后取景”时代 特别说明&#xff1a;本文所有图片素材来源于影翎官网 影翎官方介绍称&#xff1a;“全球首款”是指截至 2025 年&#xff0c;A1 是首台全面整合的全景无人机&#xff1a;无需外挂全景相机配件…

androidstudio内存大小配置

help->Edit Custom Vm option-Xmx8096m或者其他数值 改成-Xmx10240m然后设置里面的内存大小也要修改一下

vue3和elementPlus中的el-dropdown-menu中的背景样式修改

1. 效果展示2. 代码展示在el-dropdown-menu下加载类名,class"my-dropdown-menu"<el-dropdown-menu class"my-dropdown-menu"><el-dropdown-item :command"{ action: upgrade, data }">升级</el-dropdown-item><el-dropdown…

计算机网络--HTTP协议

1. 什么是 HTTP 协议全称&#xff1a;Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;作用&#xff1a;用于在服务器与客户端&#xff08;通常是浏览器&#xff09;之间传输超文本数据&#xff08;如文字、图片、视频、音频&#xff09;的应用层协议。工作…

Bee1.17.25更新Bug,完善功能.不支持NOSQL,分库分表Sharding(2.X版有)

Bee 1.17.25 正常的ORM功能都有,但不支持NOSQL, 分库分表Sharding; 若需要可使用2.X版. Bee, 接口简单&#xff0c;功能齐全&#xff0c;性能好&#xff0c;支持原生分页性能更高&#xff1b;还有分库分表 (Sharding 分片) 功能&#xff0c;也支持 MongoDB ORM. Bee Hiberna…

RAG流程全解析:从数据到精准答案

Rag流程分析第一部分&#xff1a;数据处理与向量化 原始文档进入系统&#xff0c;先经过格式识别&#xff0c;把 pdf、docx、pptx、扫描图片等统一转成文字流。文字流丢进分段器&#xff0c;按固定长度或语义边界切成若干文本块&#xff0c;每个块再生成唯一 id。如果文档里有表…

Matplotlib数据可视化实战:Matplotlib图表注释与美化入门

图表注释与标签&#xff1a;提升数据可视化效果 学习目标 通过本课程的学习&#xff0c;学员将掌握如何使用Matplotlib在图表中添加文本注释、图例、标题和轴标签&#xff0c;从而提高图表的可读性和信息传达能力。本课程将通过实际案例&#xff0c;帮助学员理解每个元素的作用…

GitLab 安全漏洞 CVE-2025-7739 解决方案

本分分享极狐GitLab 补丁版本 18.2.2, 18.1.4, 18.0.6 的详细内容。这几个版本包含重要的缺陷和安全修复代码&#xff0c;我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLab SaaS&#xff0c;技术团队已经进行了升级&#xff0c;无需用户采取任何…

C端高并发项目都有哪些

C端&#xff08;用户端&#xff09;高并发项目通常涉及大规模用户直接访问的服务&#xff0c;其核心挑战是如何在海量用户同时请求下&#xff0c;保证系统的稳定性、高性能、高可用和一致性。以下是一些典型的C端高并发项目类型和具体案例&#xff1a;​核心类型与典型案例&…