惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
T
Tailwind CSS Blog
罗磊的独立博客
B
Blog
博客园_首页
A
About on SuperTechFans
有赞技术团队
有赞技术团队
V
V2EX
U
Unit 42
I
InfoQ
IT之家
IT之家
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
H
Help Net Security

See you soon

哟,好久不见,无线打印 | See you soon 试试将文章版本化管理吧 | See you soon 使用 Quadlet 将 Podman 中的 Postgres 当作 systemd 服务运行 | See you soon 大他者,那个无时无刻都在盯着你的东西 | See you soon Laws of Software Engineering,软件工程定律 | See you soon 浅记多因素身份认证 | See you soon Linux 内核中的度量单位 | See you soon 重置 GPG 智能密钥 | See you soon 向 NAS 引入 samba | See you soon 无法重复键入的 Fcitx5 | See you soon ZFS 降级事故 | See you soon 记被 XanMod Kernel 和 AppArmor 联合坑的一次踩坑 | See you soon agent 的 skill 与 toolcall | See you soon 记一次服务器被挂恶意挖矿二进制 | See you soon 活着的 Arc | See you soon 令 acme.sh 使用 Cloudflare 的 DNS API 签发与续签证书 | See you soon 于 Tokio 中卸载 CPU Bound 任务 | See you soon 如我所见,梦破碎的时候 | See you soon 74LS 家族手册 | See you soon JDK Projects 备忘录 | See you soon 关于历史 | See you soon 用 curl 下载 OnePlus 的 ROM | See you soon 实用命令切片 | See you soon 再见,Oh My Zsh。 | See you soon 你不应该复用 strings.Builder | See you soon 博客的明日 | See you soon 被 AppArmor 击杀的 Dockge | See you soon AI 时代的自我 | See you soon 支持删除的布隆过滤器 | See you soon 基于栈的虚拟机与基于寄存器的虚拟机 | See you soon
使用 Rust 实现 SnowflakeId | See you soon
Krysztal Huang · 2024-10-23 · via See you soon

在最近的业务中更改设计的时候最终决定使用 雪花 ID (下文称之为 SID)作为数据库的主键,这样可以避免使用发号器等中间件。

但是广为使用的 snowflake 的实现实际上是线程级别的唯一,而不是分布式意义上的唯一,因此在生产上如果和分布式搭配会产生极大的问题。

怎么办?只能自己写了。

原理

SID 实际上是 Rust 的 i64,他有 64 位。但是有一位是符号位,所以实际上可以使用的只有 63 位但也绰绰有余。

所以我们的结构看起来像是这样:

| sign | data | # sign not used.

| 1bit | 63bit |

接下来我们将会介绍标准的 SID 实现。为什么是标准的?因为存在很多变种,比如 Mastodon 就是变种 SID,我们不讨论他们。

标准的 SID 包含如下信息

  • 时间戳: 41bit
  • 标识符: 10bit
  • 序列号: 12bit

所以我们的 SID 看起来应该如下

| sign | data |

| 0 | Timestamp | Identifier | Sequence Number |

| 1bit | 41bit | 10bit | 12bit |

✨ 深入黑暗

很好,现在我们理解了最基本的 SID 组成,让我们更深一步。

时间戳

标准的 SID 使用的是毫秒精度,恰好是 41 位。实际上根据 SID 的设计不同,时间戳可以是任意精度,也可以是任意起始位置。

标识符

在设计分布式系统时,我们会有多台机器(或实例)同时运行。

因此,我们必须区分它们。基于标识符为 10 位,我们可以同时拥有 1024 个实例,这简直太酷了!

序列号

你注意到 Sequence Number 了吗?它有 12 位,这意味着它在一毫秒内最多可以处理 4096 条信息(或其他东西,随便你)。

综上所述:整个系统在一毫秒内最多可以产生 1024 * 4096 = 4194304 条信息,这完全足够了!

分配完毕(不对,你是怎么做到的?!)

但我们总有可能遇到这样的情况:这一毫秒内的所有 SID 都已分配完毕!

此时,实例必须等待下一毫秒。在下一毫秒,我们将有新的 4096 个 SID 可以分配。

在这种情况下,可能需要拓展实例了 XD