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. 高通平台手机开发之LCD

    4.1. LCD 参考文档: 1) 80-NA157-174_E_DSI_Programing_Guide_B-Family_Android_Devices.pdf 2) 80-NN766-1_A_L ...

  2. JQuery实战总结一 可编辑的表格

    JQuery视频看完了,总结学习,记得在牛腩视频中的修改新闻类别的时候也使用了这样的可编辑的表格,使用到 了ajax控制界面不再刷新,轻松解决了类别的名称的修改的问题,直接提交到数据库,这样的方式比起 ...

  3. cuda中模板的使用

    模板是C++的一个重要特征,它可以让我们简化代码,同时使代码更整洁.CUDA中也支持模板,这给我们编写cuda程序带来了方便.不过cuda4.0之前和之后使用模板的方法不一样,这给我们带来了少许困难. ...

  4. android 面试之listview

    ListView优化一直是一个老生常谈的问题,不管是面试还是平常的开发中,ListView永远不会被忽略掉,那么这篇文章我们来看看如何最大化的优化ListView的性能.· 1.在adapter中的g ...

  5. 【Visual C++】游戏编程学习笔记之三:游戏循环的使用

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44208419 作者:Zee ...

  6. 框架页面高度自动刷新Javascript脚本

    实现原理:加载index.htm时候,每隔1秒钟自动调用脚本刷新框架页面代码 代码优点:只需要设置index.html框架页面中的脚本,调用加载的子页面中不需要设置任何代码. index.htm代码如 ...

  7. Shell Scripts - 条件语句,case语句,function功能

    修改之前的代码 1.判断 $1 是否为 hello,如果是的话,就显示 "Hello, how are you ?":     2.如果没有加任何参数,就提示使用者必须要使用的参数 ...

  8. DB Query Analyzer 6.02 is released, 71 articles concerned have been published

    DB Query Analyzer is presented by Master Genfeng, Ma from Chinese Mainland. It has English version n ...

  9. ActiveMQ 入门

    1.下载ActiveMQ 去官方网站下载:http://activemq.apache.org/ 2.运行ActiveMQ 解压缩apache-activemq-5.5.1-bin.zip,然后双击a ...

  10. HashMap是无序的

    一. 说明 HashMap是基于哈希表Map的实现.设计初衷主要是为了解决键值(key-value)对应关联的,HashMap的优势是可以很快的根据键(key)找到该键对应的值(value),但是我们 ...