5大分布式ID生成器优缺点简单对比

首选,不管是不是分布式系统,都有ID唯一的使用场景。而在分布式场景下,对ID的唯一性要求更严格!

常见的,我们上淘宝买东西的订单ID,就是一种分布式ID。淘宝,前期的订单id好像是14位,现在好像已经是16位,或者18位了吧。
文章图片


以我们公司的订单ID为例,它有这几个特点。

  1. ID全局唯一,不会重复
  2. ID的增长支持分布式使用
  3. ID要方便好记,并且通过ID能大概看出是什么时间创建的订单
  4. 订单ID最好还能追踪到销售员,或下单用户的ID等
  5. 增长的订单ID还不能让竞争对手发现你每天的业务量

针对第五项,浅显的问题就是不能让非核心运营者知道每天的订单量等信息。如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的订单量。所以在一些应用场景下,会需要ID无规则、不规则。

所以,设计一个好的分布式ID生成器并不是那么容易的。于是网上也有很多大公司开源这类分布式ID生成器。我今天就抽个时间,扯一扯它们之间的不同点吧。
文章图片


说到,分布式ID,我们首选想到的可能就是UUID了。

UUID

UUID(Universally Unique Identifier)的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有5种方式生成UUID。

UUID的优点:

  • 性能非常高:本地生成,没有网络消耗。

UUID 的缺点:

  1. 不易于存储:UUID太长,16字节128位,通常以36长度的字符串表示,很多场景不适用。
  2. 信息不安全:基于MAC地址生成UUID的算法可能会造成MAC地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。
  3. ID作为主键时在特定的环境会存在一些问题,比如做DB主键的场景下,UUID就非常不适用。MySQL官方有明确的建议主键要尽量越短越好,36个字符长度的UUID不符合要求;UUID还对MySQL索引不利,如果作为数据库主键,在InnoDB引擎下,UUID的无序性可能会引起数据位置频繁变动,严重影响性能。

snowflake

snowflake我就不在介绍了,我直接说它的优点:

  1. 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
  2. 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。
  3. 可以根据自身业务特性分配bit位,非常灵活。

缺点:

  • 强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。

MongDB的ObjectID可以算作是和snowflake类似方法,通过“时间+机器码+pid+inc”共12个字节,通过4+3+2+3的方式最终标识成一个24长度的十六进制字符。


美团开源的Leaf

支持多种不同模式的生成策略

  • 号段模式:该模式需要建DB表, 需要有专门的服务来提供获取id的接口, 存在网络延迟
  • Snowflake模式:为了追求更高的性能,需要通过RPC Server来部署Leaf服务,那仅需要引入leaf-core的包,把生成ID的API封装到指定的RPC框架中即可

缺点,可能就是相对来说比较复杂。


sharding-jdbc

sharding-jdbc是一个开源的主键生成组件。它的特点是简单易用,可以指定workerId或者不指定,直接通过jar的方式引入即可。看它的名字就知道,它需要DB支持。


uid-generator

uid-generator是百度开源的一个分布式ID生成器。需要建DB表,需要有专门的服务来提供获取id的接口,存在网络延迟。


现在就以我看到的而言,UUID是使用的比较多的,其他的用的相对较少,甚至有些程序员都不知道它们。

通过这些对比,我也就更深层次的了解了‘没有完美的技术’这句话。

好了,今天就到这了(`ヘ´)ノ☆(#>_<),掰掰。

Last modification:April 23rd, 2019 at 07:29 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment