what?
通用唯一标识码,在分布式系统环境下的所有元素都有唯一的标识信息。这样就不用考虑数据库创建时的重复问题。
组成>>>
从数字方面组成:
32位的16进制数字组成,以连字号分为五段,形式为8-4-4-4-12的32个字符,如:
212838e5-7067-4cd0-b65f-ea2ac8d1af5e
从结构组成:
uuid 是指在一台机器上生成的数字,保证在同一时空所有机器都是唯一的,按照OSF的制定的标准计算,用到了以太网卡地址,纳秒级时间,芯片ID码和许多可能的数字
(1)当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
(2)时钟序列。
(3)全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。
UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函数很简单地生成UUID,其格式为:xxxxxxxx-xxxx- xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12),可以从cflib 下载CreateGUID() UDF进行转换。
java使用:
需要jdk自带的java.util.UUID
使用UUID.randomUUID()--->UUID.randomUUID();
生成类似下面的UUID:
6fda6395-0c7f-45cc-87c5-9fb339e94ad5
3bc7f6ce-849e-4ab3-947a-1cd7dfc3f6c4
81954cfd-ea2f-4ba1-b3ae-fe6e44496d22
版本:
首先是一个特例--Nil UUID--通常我们不会用到它,它是由全为0的数字组成,如下:
00000000-0000-0000-0000-000000000000
1 UUIDversion1:基于时间的UUID
基于时间的UUID通常是根据随机数,时间戳,MAC地址计算得来,局域网中也可以使用ip代替>MAC,便于简化,使用MAC地址会带来安全性问题,这是这个版本被人诟病的地方,java中的>UUID就属于此类。
2 UUIDversion2:DCE安全的UUID
DCE(Distributed Computing Environment)安全的UUID和基于时间的UUID算法相同,但会把时间戳的前4位置换为POSIX的UID或GID。这个版本的UUID在实际中较少用到。
3 UUIDversion3:基于名字的UUID(MD5)
基于时间的UUID通过计算名字和名字空间的MD5散列值得到,这个版本的UUID保证了相同名字空间的不同名字的UUID唯一,不同名字空间的名字的UUID唯一,相同名字空间的相同名字的UUID一样。
4 UUIDversion4:随机UUID
根据随机数或者伪随机数生成的,但是随机的东西就像买彩票,虽然常常买不中,但是狗屎运会在不经意间到来。
5 UUIDversion5:基于名字的UUID(SHA1)
类似version3,不过使用的是SHA1算法
比较上述不同版本,我们发现,version1/3适合于分布式计算环境,可以确保唯一性。version3/5适合于一定范围内名字唯一,但是可以用于同一名字有着相同UUID的环境。至于版本四不推荐使用,虽然简单,但是简单意味着高风险。
UUID的特点:长度较长,无序,阻塞。
如果要给数据库作为主键,UUID的管理和性能也是一个缺点,因为他占用的较大,且生成效率低下,如果是给使用innoDB引擎的mysql使用还会有性能问题。所以针对上述情况,我们可以寻求更好的解决办法:
1.使用Twitter的雪花算法(snowflake)
支持分布式的snowflake算法的结果是一个long型的ID,核心思想是:使用41bit作为毫秒数,10bit作为机器ID(5bit是数据中心,5bit是机器ID),12bit作为毫秒内的流水号,相当于内序号(意味着每个节点在每毫秒内产生4096个ID),最后还有一位是符号位,永远是0
优点:
1)ID按照时间在单机上是递增的,有序
2)不依赖数据库,灵活方便,且性能优于数据库
缺点:因为在分布式环境下,机器的时钟可能会出现不同步的情况,所以会出现ID不是全局递增的情况。
2.使用Redis生成ID
核心原理:Redis是单线程的,可以用Redis的原子操作INCR和INCRBY来实现。可以使用Redis集群来提高吞吐量,比如一个集群有三个机器那么可以设置步长为3:
A:1,4,7,10
B:2,5,8,11
C:3,6,9,12
优点:
1)不依赖数据库,灵活方便,性能要比数据库生成ID要好
2)数字ID天然排序对分页或者有需要的排序有帮助
除了上述两种办法,还有其他的比如zookeeper通过其znode生成id(32位和64位),mongoDB的objectid都可以生成….