0. 概述

在使用 Prometheus 的时候发现它用的 ULID,UUID 我倒是挺熟悉的,但是,什么是 ULID 还是不太清楚,所以就了解了一下,这里做一个记录。

1. 自增 ID 为什么不行

对于 ID 来说,可能数据库自增 ID 是最常见的,从我以前开始学习 MySQL 开始就知道自增 ID 用得挺爽的,但是,后面发现,那是因为我没有用于生产环境!例如,前几天我看到的沈剑关于自增 ID 的题(自增主键,很多人以为自己懂了,然而…),发现还是不熟的,同时也清楚自增 ID 还是有很多需要担心的点的,尤其是在并发情况下。

同时,自增 ID 每次都是需要 DB 参与的,在分布式环境下存在瓶颈,同时,因为 ID 是递增的,所以可能存在数据安全问题。

2. UUID

因此,在分布式场景下,很多人选择了 UUID 作为 ID 的选择,UUID 目前有 5 个版本,分别是:

这里面常用的就是 UUID4 了,但是,即使是随即的,但是也是存在冲突的风险。

3. ULID

为了弥补 UUID 可能存在冲突的问题,于是有人改进除了 ULID,与 UUID 不同之处再与,ULID 的字符域更广,基于 32(22 + 10) 字符,而 UUID 是 16 (10+6)字符。同时它结合时间戳以及随机数,结构为:

  1. 01AN4Z07BY 79KA1307SR9X4MV3
  2. |-----------------| |----------------------------|
  3. Timestamp Randomness
  4. 48bits 80bits

和 UUID 要么基于随机数,要么基于时间戳不同,ULID 是既基于随机数,又基于时间戳,对比两种 ID 算法,可以发现 ULID 的优势有:

但是,也并不是说就是完全比 UUID 好了,因为 UUID 在有些场景下可以做到全球唯一(结合 MAC地址,真正的分布式?),而 ULID 无法做到类似的效果,在不同机器上的 ULID 碰在一起之后可能会产生冲突。

4. 参考资料