美文网首页
分布式系统中全局ID选型

分布式系统中全局ID选型

作者: 话尔loony | 来源:发表于2018-11-07 20:22 被阅读0次

    为什么越来越少的选用UUID呢

    UUID虽然能够保证ID的的唯一性,但是无法满足业务系统需要的很多其他特性,比如说:时间粗略有序性、可反解和可制造性。另外,UUID产生时使用完全的时间数据,性能比较差,并且UUID比较长(32位)、占用空间大,会间接导致数据库性能下降;以上都不是重点,最重要的是,UUID不具备有序性,会导致B+树索引在写的时候有过多的随机写操作(连续ID会产生部分的顺序写),在写的时候不能产生有序的append操作,需要进行insert操作,这样会导致将读取整个B+树节点到内存,在插入这条记录后会将整个节点写回磁盘,这种操作在记录占用空间比较大的情况下,性能会明显下降。

    基于数据库的实现

    数据库表自增ID应该是使用最广泛的id生成方式,其优点在于非常简单、对数据库索引友好、而且还能透露出一些比较常用的信息(比如,当前记录数)。

    但是缺点也是比较明显的:

    1.携带信息量较少,只能起到一个标识的作用;

    2.自增ID完全依赖数据库,在进行数据库移植、扩容、清洗数据、分库分表等操作的时候,会产生很多的麻烦;

    当然,在分库分表的时候,有一种通过设置数据库sequence的步长来确保跨数据库的ID唯一性的方案。如下图:有8个服务节点,每个节点使用一个sequence功能来产生ID,每个sequence的起始ID是不同的,而且都是依此增加,但是步长都为8,这种方案实现起来较为方便,也能达到性能目标,还能水平扩展,但是依旧存在以下问题:

        1.服务节点固定。sequence的步长也是固定的,如果需要增加服务节点,就难以进行了;

        2.还是依赖数据库,对数据库会造成压力。因为ID的产生在一些业务场景下也是高频访问的服务;

        3.由于多个sequence是疏散管理的,会提高维护成本;

    Snowflake

    Snowflake 算法是 twitter 开源的分布式 id 生成算法,采用 Scala 语言实现,是把一个 64 位的 long 型的 id,1 个 bit 是不用的,用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。

    1 bit:不用,为啥呢?因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。

    41 bit:表示的是时间戳,单位是毫秒。41 bit 可以表示的数字多达 2^41 - 1,也就是可以标识 2^41 - 1 个毫秒值,换算成年就是表示69年的时间。

    10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10台机器上哪,也就是1024台机器。但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表 2^5个机房(32个机房),每个机房里可以代表 2^5 个机器(32台机器)。

    12 bit:这个是用来记录同一个毫秒内产生的不同 id,12 bit 可以代表的最大正整数是 2^12 - 1 = 4096,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的 4096 个不同的 id。如下:

    0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000

    相关文章

      网友评论

          本文标题:分布式系统中全局ID选型

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