编程

ULID vs UUID:为什么ULID更适合在分布式系统中使用?

970 2023-04-15 11:28:00

在分布式系统中,唯一标识符(UUID)是非常常见的,它是用于标识数据或者实体的一种方式,它是基于算法生成的一个固定长度的字符串。然而,UUID也有一些缺点,例如它们很难被排序,因为它们是随机生成的,这导致了一些性能问题。而ULID则是一种新的方案,它解决了这些问题并提供了一些额外的优势。

什么是ULID?

ULID(Universally Unique Lexicographically Sortable Identifier)是一种可排序、唯一的标识符,由Alizain Feerasta在2016年提出,它结合了时间戳和随机数生成器来生成一个32位的标识符,适用于分布式系统中标识数据实体和事件等场景。

ULID规范定义了如下的格式:

01AN4Z07BY 000000000001 cc1cca9a-3ccd-11e8-9669-57e0c8c9e133Timestamp Randomness Unique Identifier10 chars 6 chars 16 chars

其中,Timestamp(时间戳)和Randomness(随机数)共占16个字符,Unique Identifier(唯一标识符)占16个字符。ULID的生成顺序是:时间戳越早的ULID排在前面,如果时间戳相同,则随机数越小的ULID排在前面。

具体地,Timestamp部分是由Unix时间戳的毫秒数(自1970年1月1日以来)进行base32编码得到的,占据了前10个字符。Randomness部分是由CSPRNG(Cryptographically Secure Pseudo-Random Number Generator,密码学安全伪随机数生成器)生成的6个字节的随机数,进行base32编码得到的,占据了接下来的6个字符。Unique Identifier部分是UUID的16个字符,用于确保ULID的全局唯一性。

下面是一个示例ULID:

01F9K1BCRK7X6T9GH6AA7YP6GWTimestamp Randomness Unique Identifier01F9K1BCRK 7X6T9G H6AA7YP6GW如何生成ULID?

生成ULID需要两个部分:时间戳和随机数。时间戳部分占据了ULID的前12个字符,使用了UTC时间,精确到毫秒。随机数部分占据了ULID的后18个字符,使用了基于CSPRNG的随机数生成器。

使用这种生成方式,可以确保生成的ULID具有全局唯一性和可排序性。此外,ULID还使用了基于时间戳的前缀,这使得可以使用前12个字符来确定生成ULID的时间。这对于调试和数据管理非常有用。

为什么要使用ULID?

ULID比UUID具有一些优势:

  • 可排序性:由于ULID基于时间戳生成,因此可以按照时间戳进行排序,这对于数据库索引和查询非常有用。另外,由于ULID采用了基于时间戳的前缀,因此可以使用前12个字符来确定时间戳,这使得调试和数据管理更加容易。
  • 可读性:ULID是由32个字符组成的,其中前12个字符是由时间戳生成的,可以通过这12个字符来确定时间戳。这对于调试和数据管理非常有用。
  • 低碰撞率:ULID的碰撞率非常低,这是因为它采用了基于时间戳的前缀和随机数生成器生成ULID,这使得生成的ULID在全球范围内都是唯一的。
  • 短且轻量级:ULID只有32个字符,而UUID有36个字符,这意味着ULID更短、更轻量级,更适合在分布式系统中使用。
  • 安全性:ULID使用了基于CSPRNG的随机数生成器来生成随机数部分,这使得它更加安全,不容易受到攻击。

如何在实践中使用ULID?

如果你想在你的应用程序中使用ULID,你可以使用现有的ULID库来生成ULID。下面是一些流行的ULID库:

  • ulid(https://github.com/ulid/spec):这是官方的ULID实现库,支持多种编程语言,包括Go、Java、JavaScript、Python和Ruby等。
  • ulid-js(https://github.com/ulid/javascript):这是JavaScript的ULID实现库,它支持在浏览器和Node.js中使用。
  • rust-ulid(https://github.com/mmacedoeu/rust-ulid):这是Rust的ULID实现库,它提供了一种安全、高效、易用的方式来生成ULID。

使用ULID的一个例子是在数据库中存储ULID作为主键,这将使得数据库中的条目按照时间排序,从而提高了数据库查询的效率。

结论

ULID是一种比UUID更好的方案,它具有可排序性、可读性、低碰撞率、短且轻量级、安全等优势。在分布式系统中,使用ULID可以提高数据库查询的效率,同时保证数据的唯一性。如果你正在构建一个分布式系统,不妨考虑使用ULID来标识你的数据和实体。