美文网首页
分布式Unique ID的生成方法

分布式Unique ID的生成方法

作者: zhanglbjames | 来源:发表于2017-06-20 14:50 被阅读0次

    ID生成器的特性

    • 唯一性
    • 时间相关
    • 粗略有序
    • 可反解
    • 可制造

    发号器(统一中央发号器)

    为了避免频繁请求获取ID,则每一次请求都请求一批ID,留着备用,所以此时ID是准连续的,不同机器之间通过多个高位bit来区分
    例如总共ID16位,则每次请求都将获取1000 0000(128)
    一共有8个机器,则高3位用来区分不同机器,比如机器A分配的高位为001,则每一请求10000000(2的7次方个128个ID),则取走的范围为:0010 0000 0000 0000 ~ 0010 0000 0111 1111,下一次取走
    0010 0000 1000 0000 ~ 0010 0000 1111 1111

    UUID本地生成

    UUID 128位

    实际上,UUID一共有多种算法,能用于TraceId的是:

    • version1: 基于时间的算法

    然后是Version1,严格守着原来各个位的规矩:
    因为时间戳有满满的60bit,所以可以尽情花,以100纳秒为1,从1582年10月15日算起(能撑3655年,真是位数多给烧的,1582年有意思么)
    节点标识也有48bit,一般用MAC地址表达,如果有多块网卡就随便用一块。如果没网卡,就用随机数凑数,或者拿一堆尽量多的其他的信息,比如主机名什么的,拼在一起再hash一把。
    顺序号这16bit则仅用于避免前面的节点标示改变(如网卡改了),时钟系统出问题(如重启后时钟快了慢了),让它随机一下避免重复。
    但好像Version 1就没考虑过一台机器上起了两个进程这类的问题,也没考虑相同时间戳的并发问题,所以严格的Version1没人实现,接着往下看各个变种吧。

    • version4: 基于随机数的算法

    先说Version4,这是最暴力的做法,也是JDK里的算法,不管原来各个位的含义了,除了少数几个位必须按规范填,其余全部用随机数表达。
    JDK里的实现,用 SecureRandom生成了16个随机的Byte,用2个long来存储。记得加-Djava.security.egd=file:/dev/./urandom,否则会锁住程序等噪音。

    本地64位ID生成

    划分命名空间本地并行生成

    将机器MAC地址和进程号进行Hash作为高位,然后时间戳(秒级别)作为中位,然后同一时间(1s内)内的自增序列
    所以(20-24bit)机器Hash + 时间戳(24-25bit)+ (16-17bit自增序列)

    参考链接
    https://mp.weixin.qq.com/s?__biz=MzA5Nzc4OTA1Mw==&mid=2659598286&idx=1&sn=3172172ccea316b0ed83429ae718b54d&chksm=8be9eadcbc9e63caa10d708274b4fa34ceffa416ef4527e10e6b7a1a2d2f32cf8592d65bf728

    相关文章

      网友评论

          本文标题:分布式Unique ID的生成方法

          本文链接:https://www.haomeiwen.com/subject/bxenfxtx.html