本文主要来聊聊分布式id的生成方案。
业务系统需要什么样的ID生成器中提出了几点目标:
对于每个标识,都需要有一个命名空间(namespace),来保证其相对唯一性。 分布式的ID生成,以Twitter Snowflake为代表的, Flake 系列算法采用的就是划分命名空间并行生成的思路。
UUID(Universally Unique Identifier)的标准型式包含32个16进制数字(每个字符0-F的字符代表4bit,共128bit),以连字号分为五段,形式为8-4-4-4-12的32+4个字符。
比如bc96c351-bea3-4e53-b0a8-d9806763dd69。
主要的格式如下:
version 4 基于随机数的算法,也是JDK里的算法,不管原来各个位的含义了,除了少数几个位必须按规范填,其余全部用随机数表达。
通过“时间+机器码+pid+inc”共12个字节,通过4+3+2+3的方式最终标识成一个24长度的十六进制字符。ObjectId是一个12字节 BSON 类型数据,有以下格式:
个64 bits的唯一long型的ID,使用其中41bit作为毫秒数,10bit作为机器编号,12bit作为毫秒内序列号。IdWorker
+———————-+————————+————————+
|timestamp(ms)42 | worker id(10) | sequence(12) |
+———————-+————————+————————+
id = timestamp | workerid | sequence (eg. 1451063443347648410)
默认采用上图字节分配方式:
snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。这个算法单机每秒内理论上最多可以生成1000*(2^12),也就是400W的ID。
Boundary flakeID 长度扩展到 128 bits:
+———————-+————————+————————+
|timestamp(ms)64 | worker id(48) | sequence(16) |
+———————-+————————+————————+
id = timestamp | workerid | sequence
由于它用 48 bits 作为 Worker ID, 和 Mac 地址的长度一样, 这样启动时不需要和 Zookeeper 通讯获取 Worker ID. 做到了完全的去中心化 它这样做的目的是用更多的 bits 实现更小的冲突概率, 这样就支持更多的 Worker 同时工作. 同时, 每毫秒能分配出更多的 ID
simpleflake取消 Worker 号, 保留 41 bits 的 Timestamp, 同时把 sequence number 扩展到 22 bits
+———————-+————————+
|timestamp(ms)42 | sequence(22)
+———————-+————————+
id = timestamp | sequence
Simpleflake 的特点:
UidGenerator
+———————-+————————+————————+
|timestamp(ms)29 | worker id(22) | sequence(13) |
+———————-+————————+————————+
id = sign + delta seconds | workerid | sequence (eg. 1451063443347648410)