唯一ID生成器snowflake

唯一ID生成器snowflake

/ˈsnəʊfleɪk/

1、应用场景

很多场景需要使用全局唯一ID,用来标识唯一一条消息,唯一一笔交易,唯一一个用户,唯一一张图片等等。
传统数据库表的自增主键是很简单的一种实现方式,前提是你没有分库,也没有分表,如果你分表了,id就会重复,失去唯一性:

唯一ID生成器snowflake_第1张图片

2、之前了解

2.1、时间戳

用时间做唯一id,这个在并发比较高或者分布式环境中基本不可行,统一时间生成的id是重复的,不满足全局唯一

2.2、利用数据库自增

依然利用数据库产生自增id,保证唯一性,和开头提到的不同之处是,单独使用一张(或固定几张)数据库表专门用来产生自增id,与业务无关,后续不再重新分表,数据量大时,可以删除早一些时候产生的数据。
这样做的好处是,实现简单,容易理解。
不好的地方是,严重依赖数据库,id产生速率受数据库性能以及连接数据库的网络影响。

2.3、利用Redis原子操作incrBy

好处:实现简单,容易理解。
坏处:依赖Redis,且Redis需要持久化。

2.4、UUID/GUID

好处:使用非常简单,不需要依赖其他设施。
坏处:太长,128bit,不适合做数据库主键。

3、snowflake

通常情况下,用时间来表示是最简单的,如果同一时间(毫秒)有很多请求进来怎么办?
时间戳后面拼接上一个数字,这个数字可以通过锁控制每次递增,每毫秒清零,重新开始递增。

即便这样,只是解决了单机的问题,如果是分布式环境,不同的机器,还是可能产生一样的id的,这怎么解决?
在上述时间戳和数字的基础上在拼接上机器的id,这样就不会重复了。

不同的数据中心,机器id是可能重复的,怎么搞?
再拼接上数据中心的id就行了。

不同的星球上。。。

思想朴实无华,但是大道至简。

最终产生的id是这个样子的,时间戳,工作机器id,序列号可以根据实际需要调整长度(通常情况下不需要调整,完全够用),总体64bit就行:

,时间戳,工作机器id,序列号可以根据实际需要调整长度(通常情况下不需要调整,完全够用),总体64bit就行:


你可能感兴趣的:(算法)