浅析分布式ID生成算法(UUID、Snowflake、Leaf)

简介: 浅析分布式ID生成算法(UUID、Snowflake、Leaf)

一、雪花算法



1、雪花算法简介

     

SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上是保持自增的。

       

由于在Java中64bit的整数是long类型,所以在Java中SnowFlake算法生成的id就是long来存储的。


2、雪花算法生成ID的结构

9e3a38cbbc7a43af97b109aa975a142c.png

1、1bit,不用,因为二进制中最高位是符号位,1表示负数,0表示正数。生成的id一般都是用整数,所以最高位固定为0。


2、41bit-时间戳,用来记录时间戳,毫秒级。

- 41位可以表示 (2^41-1) 个数字,

- 如果只用来表示正整数(计算机中正数包含0),可以表示的数值范围是:0 至 2^41-1 ,减1是因为可表示的数值范围是从0开始算的,而不是1。

- 也就是说41位可以表示 2^41-1 个毫秒的值,转化成单位年则是69年


3、10bit-工作机器id,用来记录工作机器id。

 - 可以部署在 2^10=1024 个节点,包括5位datacenterId和5位workerId

- 5位(bit)可以表示的最大正整数是 2^5-1=31 ,即可以用0、1、2、3、....31这32个数字,来表示不同的datecenterId或workerId


4、12bit-序列号,序列号,用来记录同毫秒内产生的不同id。

- 12位(bit)可以表示的最大正整数是 2^12-1=4095 ,即可以用0、1、2、3、....4094这4095个数字,来表示同一机器同一时间截(毫秒)内产生的4095个ID序号。


3、雪花算法能够保证


(1)所有生成的id按时间趋势递增


(2)整个分布式系统内不会产生重复id(因为有datacenterId和workerId来做区分)


4、雪花算法优缺点


优点:


(1)高性能高可用:生成时不依赖于数据库,完全在内存中生成。

(2)容量大:每秒中能生成数百万的自增ID。

(3)ID自增:存入数据库中,索引效率高。


缺点:


(1)依赖与系统时间的一致性,如果系统时间被回调,或者改变,可能会造成id冲突或者重复。

(2)不一定是全局递增的


5、雪花算法的优化——时钟回拨问题

     

保存过去一段时间内每一台机器在当前这一毫秒产生的ID的最大值,比如使用Map形式,就是<machine_id,max_id>,这样如果某台机器发生了时钟回拨,直接在这台机器对应的max_id的基础上继续自增生成ID即可。


6、源码


参考:雪花算法的原理和实现Java_雨夜青草的博客-CSDN博客_雪花算法


二、UUID



1、UUID简介


UUID(Universally Unique Identifier)的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有5种方式生成UUID,详情见IETF发布的UUID规范 A Universally Unique IDentifier (UUID) URN Namespace。  


2、UUID的优缺点


优点:    

(1)性能非常高:本地生成,没有网络消耗。

     

缺点:

(1)不易于存储:UUID太长,16字节128位,通常以36长度的字符串表示,很多场景不适用;

(2)信息不安全:基于MAC地址生成UUID的算法可能会造成MAC地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。

(3)ID作为主键时在特定的环境会存在一些问题,比如做DB主键的场景下,UUID就非常不适用:


1、MySQL官方有明确的建议主键要尽量越短越好[4],36个字符长度的UUID不符合要求。 4c22322ea27f47c4b3178032a98ae18d.png


2、对MySQL索引不利:如果作为数据库主键,在InnoDB引擎下,UUID的无序性可能会引起数据位置频繁变动,严重影响性能。


三、Leaf




参考:Leaf——美团点评分布式ID生成系统 - 美团技术团队

       9种分布式ID生成之美团(Leaf)实战_程序员内点事-CSDN博客_leaf 美团


相关:一口气说出 9种 分布式ID生成方式,面试官有点懵了


相关文章
|
4天前
|
算法 关系型数据库 MySQL
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
在分布式系统中,确保每个节点生成的 ID 唯一且高效至关重要。Snowflake 算法由 Twitter 开发,通过 64 位 long 型数字生成全局唯一 ID,包括 1 位标识位、41 位时间戳、10 位机器 ID 和 12 位序列号。该算法具备全局唯一性、递增性、高可用性和高性能,适用于高并发场景,如电商促销时的大量订单生成。本文介绍了使用 Go 语言的 `bwmarrin/snowflake` 和 `sony/sonyflake` 库实现 Snowflake 算法的方法。
17 1
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
|
3月前
|
算法 Go
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
18天前
|
NoSQL 算法 关系型数据库
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
本文详解分布式全局唯一ID及其5种实现方案,关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
|
3月前
|
SQL 算法 Serverless
B端算法实践问题之使用concat_id算子获取用户最近点击的50个商品ID如何解决
B端算法实践问题之使用concat_id算子获取用户最近点击的50个商品ID如何解决
28 1
|
3月前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
3月前
|
存储 算法 数据挖掘
技术分享:从雪花算法生成订单ID的抉择与反思
【8月更文挑战第17天】在软件开发的浩瀚征途中,技术选型如同航海中的罗盘,指引着项目前进的方向。今天,我想与大家分享一段关于“用雪花算法生成订单ID,现在我有点后悔了”的亲身经历,希望通过这段故事,为大家在技术选型时提供一些参考与启示。
89 0
|
1月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
3月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
110 2
基于Redis的高可用分布式锁——RedLock
|
3月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
7天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
40 16