首页 > 其他分享 >面试场景题系列:分布式系统中的唯一ID生成器

面试场景题系列:分布式系统中的唯一ID生成器

时间:2024-12-25 15:55:33浏览次数:5  
标签:UUID 生成器 生成 分布式系统 工单 服务器 ID

1.场景需求需求界定

•ID必须是唯一的。

•ID只包含数字。

•ID长为64位。

•ID按日期排序。

•可以每秒生成超过10,000个唯一ID。

2.高层级的设计

在分布式系统中,有多个方法可以用来生成唯一ID。我们考虑的方法有:

•多主复制(Multi-master Replication)。

•通用唯一标识符(Universally Unique Identifier,UUID)。

•工单服务器(Ticket Server)。

•推特的雪花(Snowflake)系统。

我们来看看它们的工作原理以及优缺点。

2.1.多主复制

图-1

这个方法利用了数据库的自增特性。我们并不是把下一个ID加1,而是加k,这里k是正在使用的服务器数量。在图-1中,生成的下一个ID等于同一个服务器上的前一个ID加2。这种方法解决了一些可扩展性问题,因为ID可以随着服务器数量的增加而同步扩展。但是这个方法也有一些重大缺点。

•很难与多个数据中心一起扩展,需要进行额外的同步和协调操作。

•在分布式环境下,多个服务器同时生成ID,可能导致ID并不连续,也即ID并不随时间递增。

•当服务器被添加或者移除时,ID不能很好地随之变化。

2.2 UUID

UUID是另一种获取唯一ID的简单方法。UUID是一个128位的数字,用来标识计算机系统中的信息。UUID重复的概率非常低。这里引用维基百科的说法,“每秒产生10亿个UUID且持续约100年,产生一个重复UUID的概率才达到50%。”。下面是一个UUID的例子:09c93e62-50b4-468d-bf8a-c07e1040bfb2。UUID可以独立地生成而不需要在服务器之间做任何协调。图-2展示了采用UUID的设计。在这个设计中,每个Web服务器都含有一个ID生成器且负责独立地生成ID。

图-2

UUID方法的优点是:

•生成ID很简单。服务器之间不需要任何协调,所以不会有任何同步问题。

•系统易于扩展,因为每个Web服务器只负责生成它们自己使用的ID。ID生成器可以很容易地随Web服务器一起扩展。

其缺点是:

•ID长128位,但是我们要求的是64位。

•ID并不随时间增加。

•ID可能是非数字的。

2.3 工单服务器

工单服务器也是生成唯一ID的重要方法。Flicker研发了工单服务器来生成分布式主键。值得一提的是这个方法的工作原理。这个方法的思想是利用中心化的单数据库服务器(工单服务器)的自增特性(参见图-3)。

图-3

工单服务器方法的优点是:

•ID为数字。

•容易实现,适用于中小型应用。

其缺点是存在单点故障。单个工单服务器意味着,如果这个服务器发生故障,所有依赖于它的系统就都会面临问题。为了避免单点故障,我们可以设置多个工单服务器。但是这会引入新的挑战,比如数据同步问题。

2.4雪花系统

前面介绍了几个ID生成方法的原理,但是这些方法中没有一个满足我们的特定需求,因此我们需要另一种方法。推特的唯一ID生成系统叫作“Snowflake”(雪花),它很有启发性,而且能满足我们的需求。分布解决是个好办法。我们不直接生成一个ID,而是把一个ID分成不同的部分。图-4展示了一个64位ID的构成。

图-4

每个部分的含义如下所述。

•符号位(1位):它始终为数字0,留作未来使用。它有可能被用来区分有符号数和无符号数。

•时间戳(41位):它是从纪元或者自定义纪元开始以来的毫秒数。我们使用Snowflake默认纪元(epoch)1,288,834,974,657,相当于UTC时间2010年11月4日01:42:54。

•数据中心ID(5位):最多可以有32个(25)数据中心。

•机器ID(5位):每个数据中心最多可以有32台(25)机器。

•序列号(12位):对于某个机器/进程,每生成一个ID,序列号就加1。这个数字每毫秒开始时都会被重置为0。

3.深入设计

我们讨论了在分布式系统中设计唯一ID生成器的各种方法,最后选择了基于推特Snowflake ID生成器的方法。接下来,我们进行深入的设计。

图-5

数据中心ID和机器ID通常在起始阶段就选好了,一旦系统运行起来,这两个部分就是固定的。对数据中心ID和机器ID所做的任何更改都需要仔细审查,因为对这些值的意外改动可能会导致ID冲突。时间戳和序列号是在ID生成器运行后才生成的。

3.1时间戳

41位的时间戳是ID中最重要的部分。随着时间的推移,时间戳不断增长,因此ID可以按时间排序。图-6展示了一个例子,将二进制表示的时间戳转换成UTC时间。你也可以用类似的方法把UTC时间转换成二进制表示。

41位能表示的最大时间戳是241-1,即2,199,023,255,551毫秒(ms),约等于69年(计算方法为2,199,023,255,551÷1000÷365÷24÷3600)。这意味着ID生成器可以工作约69年。如果我们把纪元开始时间定制得离今天的日期足够近,就可以延迟溢出时间。69年后,我们需要一个新的纪元时间或者采用别的技术来迁移ID。

图-6

3.2序列号

序列号有12位,相当于4096种组合(212)。这个部分一般是0,除非在1毫秒内同一个服务器生成了多个ID。理论上,一个服务器每毫秒最多生成4096个新ID。

4.总结

在本文中,我们讨论了设计一个唯一ID生成器的不同方法:多主复制、UUID、工单服务器和类似推特Snowflake的唯一ID生成器。我们最后选择了Snowflake,因为它支持我们的所有用例,并且可以在分布式环境中扩展。如果在面试的最后还有一些时间,你可以讨论下面这些议题。

•时钟同步。在我们的设计里,我们假设生成ID的服务器都有同样的时钟。但是,当服务器运行在多核上时,这个假设可能并不成立。在多机器的场景中也存在同样的挑战。时钟同步的解决方案不在本文的讨论范围内;但是,知道这个问题的存在是很重要的。网络时间协议(NTP)是这个问题最流行的解决方案,感兴趣的读者可以参阅维基百科中的“Network Time Protocol”词条。

•调整ID各部分的长度。比如,对于低并发且长时间持续运行的应用,减少序列号部分的长度,增加时间戳部分的长度,生成的ID会更高效。

•高可用性。因为ID生成器是一个非常关键的系统,所以它必须是高可用的。

标签:UUID,生成器,生成,分布式系统,工单,服务器,ID
From: https://blog.csdn.net/launch2020/article/details/144721289

相关文章

  • Chapter 8, 9 B-CIDS: 5 pillars of AI preparation → Jumpstart Approach
    B-CIDSAI-Readiness:AcompanyisAI-readywhenitcansmoothlyprogressfromAIconcepttoimplementationandbenefitrealization,anddosoconsistently.Preparation:AchievingAI-readinessisacomprehensiveprocessinvolvingcompanyculture,talent,......
  • 最新的强大的文生视频模型Pyramid Flow 论文阅读及复现
    《PYRAMIDALFLOWMATCHINGFOREFFICIENTVIDEOGENERATIVEMODELING》论文地址:2410.05954https://arxiv.org/pdf/2410.05954项目地址:jy0205/Pyramid-Flow:用于高效视频生成建模的金字塔流匹配代码https://github.com/jy0205/Pyramid-Flow论文提出了一种新的视频生成模型,......
  • X80 DRONE APP Technical Support Guide
    X80DRONEAPPTechnicalSupportGuideWelcometotheX80DRONEAPPTechnicalSupportGuide.Thisguidewillprovideanoverviewoftheapp’skeyfeaturesandoffertroubleshootingtips.Ifyouencounteranyissuesnotcoveredhere,pleasereachouttoour......
  • RTSP播放器EasyPlayer.js遇到Android播放器修复播放画面卡在第一帧问题
    在数字化时代,流媒体技术已经成为信息传播和娱乐消费的重要方式。随着互联网技术的飞速发展和移动设备的普及,流媒体服务正在重塑我们的生活和工作方式。从视频点播、在线直播到音乐流媒体,流媒体技术的广泛应用不仅改变了内容的分发和消费模式,也为内容创作者和消费者提供了前所未有......
  • PySide6-FluentUI-QML 使用记录 python + pyside6 + qml
    PySide6-FluentUI-QML是一个ui库,官网地址为https://github.com/zhuzichu520/FluentUI作用:美化qml文件,快速构建项目简单使用1.pipinstallpyside6安装pyside62.pipinstallPySide6-FluentUI-QML安装PySide6-FluentUI-QML3.加载fluentui##main.pyimportsysimpor......
  • 源码编译geoserver(idea)
    官方教程:https://docs.geoserver.org/main/en/developer/quickstart/intellij.html 从git存储库中检出源代码:gitclonehttps://github.com/geoserver/geoserver.gitgeoserver列出可用的分支:%gitbranch2.21.x2.22.x*main选择main最新动态:%gi......
  • 正版SOLIDWORKS软件价格,企业购买详细解析方案
    **正版SOLIDWORKS软件价格详解**在工程设计领域,SOLIDWORKS作为一款备受推崇的三维CAD设计软件,其正版价格一直是用户关注的焦点。SOLIDWORKS软件以其强大的功能、灵活的操作性和卓越的性能,赢得了全球众多企业和设计师的青睐。正版SOLIDWORKS软件的价格根据版本的不同而有所差......
  • 通过Java Bean Validation API
    通过JavaBeanValidationAPI的验证,对字符串、集合、数组等对象的大小进行验证。(如:通过限制参数的大小,来防止SQL注入)1、添加依赖<!--HibernateValidator--><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactI......
  • mysql 新增ID
    mysql新增ID|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------------|-------------|-------------|-------------|---------......
  • jsgrid多个自定义控件按钮?
    jsgrid多个自定义控件按钮?|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------------|-------------|-------------|-------------|......