使用 Rust 实现 SnowflakeId
在最近的业务中更改设计的时候最终决定使用
但是广为使用的
怎么办?只能自己写了。
原理
SID 实际上是 Rust 的 i64,他有 64位。但是有一位是符号位,所以实际上可以使用的只有 63 位但也绰绰有余。
所以我们的结构看起来像是这样:
1 | |
接下来我们将会介绍标准的 SID实现。为什么是标准的?因为存在很多变种,比如 Mastodon 就是变种SID,我们不讨论他们。
标准的 SID 包含如下信息
- 时间戳: 41bit
- 标识符: 10bit
- 序列号: 12bit
所以我们的 SID 看起来应该如下
1 | |
✨ 深入黑暗
很好,现在我们理解了最基本的 SID 组成,让我们更深一步。
时间戳
标准的 SID 使用的是毫秒精度,恰好是 41 位。实际上根据 SID的设计不同,时间戳可以是任意精度,也可以是任意起始位置。
标识符
在设计分布式系统时,我们会有多台机器(或实例)同时运行。
因此,我们必须区分它们。基于标识符为 10 位,我们可以同时拥有 1024个实例,这简直太酷了!
序列号
你注意到 Sequence Number 了吗?它有 12位,这意味着它在一毫秒内最多可以处理 4096条信息(或其他东西,随便你)。
综上所述:整个系统在一毫秒内最多可以产生1024 * 4096 = 4194304 条信息,这完全足够了!
但我们总有可能遇到这样的情况:这一毫秒内的所有 SID 都已分配完毕!
此时,实例必须等待下一毫秒。在下一毫秒,我们将有新的 4096 个 SID可以分配。
在这种情况下,可能需要拓展实例了 XD