全局唯一ID
创始人
2024-02-15 09:53:50

文章目录

      • 前言
      • MongoDB ObjectId
      • Twitter Snowflake
      • UUID

前言

  • 基于数据库设置其实初始值,以及增量步长。
  • 基于ZK,Redis,改良雪花集中式服务生成,远程调用获取id。
  • 基于并行空间划分,Snowflake(8Byte字节64bit位),MongoDB ObjectId(12字节),UUID(16字节)
  • 基于全随机UUID(16字节)

MongoDB ObjectId

12-byte MongoDB ObjectId 的结构是:

  • a 4-byte value representing the seconds since the Unix epoch,.
  • a 3-byte machine identifier.
  • a 2-byte process id.
  • a 3-byte counter, starting with a random value.

可以看出,这个方案所支持的最小划分粒度是「秒 * 进程实例」,单进程实例的每秒容量是 3-byte (24-bit),也就是接近16777216个ID。

即每个实例每秒1600多W。

看代码(MonogoDB 3.3.x Java Driver)

1. Timestamp

图片

2. Machine Identifier

图片

3. Process ID

图片

4. COUNTER

图片

此处需要注意的是MongoDB的 NEXT_COUNTER 其初始值是一个随机数,这是有利于分库分表的。因为在小并发的条件下,非随机数的初始值,容易产生 偏库偏表, 不均匀的现象。

Twitter Snowflake

64-bit 长的 Snowflake ,它的结构是:

  • 1-bit reserved
  • 41-bit timestamp millisecond
  • 10-bit machine id
  • 12-bit sequence

所支持的最小划分粒度是「毫秒 * 线程」,单线程(Snowflake 里对应的概念是 Worker)的每毫秒容量是12-bit,也就是接近4096。

即每个实例每秒4096000(400w)

初始化时间自己指定,例如:

// Thu, 04 Nov 2010 01:42:54 GMT
twepoch = 1288834974657L;

1. Timestamp

 System.currentTimeMillis() - twepoch

2. Machine Identifier

同上

3. Process ID

同上

4. Sequence

if (lastTimestamp == timestamp) {// 相同毫秒内,序列号自增sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {// 同一毫秒的序列数已经达到最大, 则等待下一个毫秒时间,即使用下一秒 sequence默认0Ltimestamp = tilNextMillis(lastTimestamp);}
} else {// 不同毫秒内,序列号置为 [1 - 3) 随机数 即 1或者2 防止每毫秒初始值相同sequence = ThreadLocalRandom.current().nextLong(1, 3);
}

sequence初始值是一个[1 - 3) 随机数,这是有利于分库分表的。因为在小并发的条件下,非随机数的初始值,容易产生 偏库偏表, 不均匀的现象。

闰秒问题以及运行中时钟回拨问题

闰秒会出现把协调世界时向前拨1秒(负闰秒,最后一分钟为59秒)或向后拨1秒(正闰秒,最后一分钟为61秒);

// 当前时间小于上次时间,即出现闰秒或者时钟回溯了
if (timestamp < lastTimestamp) {long offset = lastTimestamp - timestamp;if (offset <= 5) { // 回溯时差 如果小于等于 5 mstry {wait(offset << 1); //等个2倍时间 再获取时间戳timestamp = timeGen(); if (timestamp < lastTimestamp) { // 还小则抛出异常throw new RuntimeException("时钟回调了 拉了裤");}} catch (Exception e) {throw new RuntimeException(e);}} else {throw new RuntimeException("时钟回调了 拉了裤");}
}

延迟等待解决,实际应用项目: 美团的leaf,。

UUID

参见另一篇:UUID的5个版本

  • 版本1 - UUID 是根据时间和 节点ID(通常是MAC地址)生成;时间+MAC,不安全

  • 版本2 - UUID是根据标识符(通常是组或用户ID)、时间和节点ID生成;

  • 版本3、版本5 - 确定性UUID 通过散列(hashing)名字空间(namespace)标识符和名称生成;

  • 版本4 - UUID 使用随机性或伪随机性生成。

一般的,使用的最多的是UUID Version 4,很大程度上是因为其依赖的其他服务最少。

Java只支持生成版本3和版本4的UUID

V4 随机UUID,UUID.randomUUID().toString()

V4 随机UUID重复概率问题?

V4随机版本有一定的重复概率但是极低,直接上结论,来着维基百科

在 103 万亿 个 版本4 UUID 中找到重复的概率是(十亿分之一)。

参考

  • 生成全局唯一ID的3个思路,来自一个资深架构师的总结 - 王延炯

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...