UUID那些事

UUID 是一个全局唯一的通用识别码。它使用某种规则,而不是某种中心化的自增方式,来保证这个识别码的全局唯一性。UUID 有非常多的使用场景,比如在分布式系统中,需要生成全局唯一 ID 来进行日志记录。UUID 的生成规则由 rfc4122 来进行定义。

UUID 和 GUID 的区别

其实是没有区别的,GUID 是微软按照 UUID 的规则实现的一套方法。它本质的目的也是为了保证全局唯一性。微软已经使用 GUID 在 Windows 的 COM,ActiveX 等技术上了。但是这里注意的一点是,UUID 本质是有多种版本的,GUID 也是在不同的使用场景实现的是不同的 UUID 版本,比如 COM 是使用 UUID 版本1 进行实现的。所以,在聊 UUID 和 GUID 是不是一样的时候,附带的信息应该了解清楚版本信息。

版本

UUID 是有不同的版本的,每个版本有不同的适用场景,比如,版本4 建议使用随机方式生成所有的可变因子。在很多场景下,这个其实是一个非常方便的实现方式。版本1 使用的是 时间戳+时钟序列+节点信息(机器信息)在一些分布式系统场景下是能严格保证全局唯一的。twitter 的 snowflake 可以看作是是 UUID 版本1 的简化版。

到现在为止,UUID 一共有5个实现版本:

  • 版本1: 严格按照 UUID 定义的每个字段的意义来实现,使用的变量因子是时间戳+时钟序列+节点信息(Mac地址)
  • 版本2: 基本和版本1一致,但是它主要是和 DCE( IBM 的一套分布式计算环境)。但是这个版本在 ietf 中也没有具体描述,反而在DCE 1.1: Authentication and Security Services这篇文档中说到了具体实现。所以这个版本现在很少使用到,并且很多地方的实现也都忽略了它。
  • 版本3: 基于 name 和 namespace 的 hash 实现变量因子,版本3使用的是 md5 进行 hash 算法。
  • 版本4: 使用随机或者伪随机实现变量因子。
  • 版本5: 基于 name 和 namespace 的 hash 实现变量因子,版本5使用的是 sha1 进行 hash 算法。

不管是 UUID 的哪个版本,它的结构都是一样的,这个结构是按照版本1进行定义的,只是在其他版本中,版本1中的几个变量因子都进行了变化。

UUID 基本结构

UUID 长度是128bit,换算为16进制数值(每4位代表一个数值)就是有32个16进制数值组成,中间使用4个-进行分隔,按照8-4-4-4-12的顺序进行分隔。加上中间的横杆,UUID有36个字符。

这个图是 UUID 的具体结构。它的可变因子有三个,Timestamp 时间戳,Clock Sequence时钟序列,node节点信息。然后由他们的不同部分组成这个 UUID。

Timestamp

时间戳是其中一个可变因子。时间戳有长度为 60bit。它代表现在当前UTC时间(必须使用UTC时间,这样就统一了时区)和1582-10-15 00:00:000000000,每100纳米加一。对于无法获取UTC时间的系统,由于获取不到UTC,那么你可以统一采用 localtime。(实际上一个系统时区相同就可以了)。

有了时间戳之后,结构图中的time_low,time_mid,time_hi就知道了

time_low

是 timestamp 60bit 中的 0~31bit,共32bit

time_mid

是 timestamp 60bit 中的 32~47bit,共16bit

time_hi_and_version

这个字段的意思很明确,就是包含两个部分,version 和 time_hi。version 占用 bit 数为4. 代表它最多可以支持31个版本。time_hi就是timestamp剩余的12bit,一共是16bit。

Clock Sequence

如果计算 UUID 的机器进行了时间调整,或者是 nodeId 变化了(主机更换网卡),和其他的机器冲突了。那么这个时候,就需要有个变量因子进行变化来保证再次生成的 UUID 的唯一性。

其实Clock Sequence的变化算法很简单,当时间调整,或者 nodeId 变化的时候,直接使用一个随机数,或者,在原先的Clock Sequence值上面自增加一也是可以的。

Clock Sequence 一共是14bit

clock_seq_low

是 Clock Sequence 中的 0~7 bit 共8bit

clock_seq_hi_and_reserved

包含两个部分,reserved 和 clock_seq_hi。其中 clock_seq_hi 为 Clock Sequence 中的 8~13 bit 共6个bit,reserved是2bit,reserved 一般设置为10。

node

node 这个变量因子由MAC地址组成,通常是IP地址。它有48bit大小。其中的 0-15填入node(0-1)的位置,16-47填入node(2-5)的位置。

不同版本

基本上,按照上节说的已经把 UUID 的结构构成说明清楚了。基本上这个结构构成是 UUID version1 的定义。我们可以看到,它有的变量因子是 timestamp, clock sequence, node。

在不同版本中,这几个变量因子的含义是不同的。

version4

在version4 中,timestamp,clock sequence, node都是随机或者伪随机的。

version3&5

version3和5 叫做基于 name 和 namesapce 的 hash 结构生成。其中的name 和namespace 基本上和我们很多语言的命名空间,类名一样,它的基本要求就是,name + namespace 才是唯一确定hash串的标准。换句话说,一样的namespace + name 使用的hash算法(比如version3的md5)计算出来的结果必须是一样的,但是不同的 namespace 中的同样的 name 生成的结果是不一样的。

version3 和 version5 中的三个变量因子都是由hash 算法保证的,version3是 md5, version5是sha1。

参考文档

wiki
理解UUID
分布式UniqueID的生成方法一览
关于UUID的二三事

UUID那些事的更多相关文章

  1. JAVA UUID 生成

    UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的.通常平台会提供生成UUID的API.UUID按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址.纳秒级时间.芯 ...

  2. java生成随机字符串uuid

    GUID是一个128位长的数字,一般用16进制表示.算法的核心思想是结合机器的网卡.当地时间.一个随即数来生成GUID.从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义 ...

  3. iOS 证书那些事

    关于开发证书配置(Certificates & Identifiers & Provisioning Profiles),相信做iOS开发的同学没少被折腾.对于一个iOS开发小白.半吊 ...

  4. Java日志性能那些事(转)

    在任何系统中,日志都是非常重要的组成部分,它是反映系统运行情况的重要依据,也是排查问题时的必要线索.绝大多数人都认可日志的重要性,但是又有多少人仔细想过该怎么打日志,日志对性能的影响究竟有多大呢?今天 ...

  5. 如何在高并发的分布式系统中产生UUID

    一.数据库发号器 每一次都请求数据库,通过数据库的自增ID来获取全局唯一ID 对于小系统来说,这是一个简单有效的方案,不过也就不符合讨论情形中的高并发的场景. 首先,数据库自增ID需要锁表 而且,UU ...

  6. 刚安装Fedora 23工作站后,你必须要做的24件事

    [51CTO.com快译]Fedora 23工作站版本已发布,此后我们就一直在密切关注它.我们已经为新来读者介绍了一篇安装指南:<Fedora 23工作站版本安装指南> 还有一篇介绍如何从 ...

  7. spring data jpa、Hibernate开启全球唯一UUID设置

    spring data jpa.Hibernate开启全球唯一UUID设置 原文链接:https://www.cnblogs.com/blog5277/p/10662079.html 原文作者:博客园 ...

  8. Linux系统启动那些事—基于Linux 3.10内核【转】

    转自:https://blog.csdn.net/shichaog/article/details/40218763 Linux系统启动那些事—基于Linux 3.10内核 csdn 我的空间的下载地 ...

  9. 文件上传中UUID的解读

    UUID简介如下:1.简介UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software F ...

随机推荐

  1. C语言的引用计数与对象树

    引用计数与对象树 cheungmine 2013-12-28 0 引言 我们经常在C语言中,用指针指向一个对象(Object)的结构,也称为句柄(Handle),利用不透明指针的技术把结构数据封装成对 ...

  2. gdb学习(一)[第二版]

    概述 gdb是GNU debugger的缩写,是编程调试工具. 功能 1.启动程序,可以按照用户自定义的要求随心所欲的运行程序. 2.可让被调试的程序在用户所指定的断点处停住 (断点可以是条件表达式) ...

  3. centos6.2安装桌面环境 与中文支持

    yum groupinstall "X Window System" //安装Xorgyum groupinstall "Desktop" //安装GNOMEy ...

  4. 初涉IPC,了解AIDL的工作原理及使用方法

    初涉IPC,了解AIDL的工作原理及使用方法 今天来讲讲AIDL,这个神秘的AIDL,也是最近在学习的,看了某课大神的讲解写下的blog,希望结合自己的看法给各位同价通俗易懂的讲解 官方文档:http ...

  5. linux下D盘(适用于U盘、硬盘等一切移动存储设备)策略(比格式化猛,因为是不可恢复!)

    关于这样的资料,在百度上还是比较少的,今天就共享出来,在电脑主机上插上你的U盘,输入以下命令: dd if=/dev/zero of=/dev/sdb  bs=1024 count=102400   ...

  6. 熊猫猪新系统测试之三:iOS 8.0.2

    本来本猫要等到8.1版本出来后再做测试的,结果等来等去就是迟迟不推送更新呀!说好10月20号的iOS 8.1呢?为了一鼓作气写完,就先不等了.先拿手头的iOS 8.0.2系统做一下测试吧! 8.x系统 ...

  7. redis删除所有key

    flushdb 删除当前数据库的所有keyflushall  删除所有数据库的所有keydbsize   返回当前数据库的key的数量

  8. iOS 字体权重weight

    UIFontWeightUltraLight  - 超细字体 UIFontWeightThin  - 纤细字体 UIFontWeightLight  - 亮字体 UIFontWeightRegular ...

  9. 2018 ACM-ICPC World Finals B.Comma Sprinkler

    WF里面最简答一题,就是一个dfs就可以了,已经访问过的点可以不再访问 #include <algorithm> #include <cmath> #include <c ...

  10. RHEL7.0 Docker离线安装以及实战笔记

    1.概述 最近在琢磨一个事--在RHEL 7.0系统上离线安装使用Docker.然后配置JAVAEE环境,发布Web服务.在网上查了资料,大多数是在线安装的,其他的要么是环境不同,要么资料包找不到了. ...