跳到主要内容

雪花 ID(Snowflake)怎么解:从一个 64 位数字读出生成时间

雪花 ID 把时间戳放在高位,后面跟机器号和序列号。本文讲清结构、为什么高位是时间戳、Twitter 怎么发明它,并用真实 ID 现场解出毫秒级生成时间。

发布于 作者 李雷
#雪花ID #Snowflake #分布式ID #时间戳 #后端

雪花 ID(Snowflake)怎么解:从一个 64 位数字读出生成时间

第一次接触雪花 ID 是在排查一张订单表。主键是一串十九位的长数字,看着像随机值,可同事说「这里面藏着下单时间」。我半信半疑,把其中一个数字拆开,真的还原出了精确到毫秒的创建时刻。那一刻我才明白,这种 ID 不是随机分配的,而是一个被精心打包过的 64 位结构。

雪花 ID 到底是什么

雪花 ID(Snowflake)是一种生成分布式唯一主键的方案,核心目标只有一个:在很多台机器同时生成 ID 的情况下,不用任何中心协调,也能保证全局不重复,而且大致按时间有序。

它的载体是一个 64 位整数。从高位到低位,这 64 位被切成四段:

  • 1 位符号位,永远留空,保证整个数字是正数。
  • 41 位毫秒时间戳,记录这个 ID 是哪一毫秒生成的。
  • 中间一段机器号 / worker 号,标识是哪台节点生成的。
  • 末尾一段序列号,同一毫秒内生成多个 ID 时自增,用来区分。

Twitter 的经典布局是 41 位时间戳 + 5 位数据中心 + 5 位 worker + 12 位序列。12 位序列意味着同一台机器在同一毫秒里最多能产出 4096 个不重复的 ID,这个量级对绝大多数业务都够用。

为什么是 Twitter 发明的

雪花算法诞生于 2010 年的 Twitter。当时他们正从 MySQL 自增主键迁移走,自增 ID 依赖单点,扩展性差;而 UUID 又太长、无序,对数据库索引不友好。Twitter 需要一种既紧凑、又能在成百上千台机器上独立生成、还能按时间排序的 ID,于是设计了 Snowflake,并把它开源。

后来 Discord、Instagram 都采用了同款思路,各自只是改了纪元和位宽。所以今天你在很多平台看到的那串长数字,本质上都是雪花的变体。

关键一点:高位是时间戳,所以趋势递增

雪花 ID 最值得记住的设计,就是把 41 位时间戳放在最高位。这带来一个直接结果:数值大小基本等于生成时间的先后。先生成的 ID 一定小于后生成的 ID(同一毫秒内由序列号区分),整体趋势递增。

趋势递增对数据库是大利好。B+ 树索引最怕随机写入,因为新数据会插到树的各个位置,引发频繁的页分裂;而趋势递增的主键总是追加在末尾,写入顺畅,索引也更紧凑。这正是雪花比纯随机 UUIDv4 更适合做主键的根本原因。想深入对比可以看 /zh/t/uuid-v7-generator/,UUIDv7 把时间戳也提到了高位,走的是同一条路。

从一个雪花 ID 解出生成时间

光说结构不够直观,我们拿一个真实的 ID 走一遍。

输入:1541815603606036480,纪元选 Twitter。

解出来是:

  • 时间戳:2022-06-28 16:07:40 UTC
  • 机器号:378
  • 序列号:0

原理是:先把这个 64 位数字右移,取出最高的 41 位拿到相对毫秒数,再加回 Twitter 的纪元 1288834974657(对应 2010-11-04),就得到真正的 Unix 毫秒时间。这里有个坑:纪元不是 1970 年,而是各平台自定的起点。同一个数字,用 Twitter 纪元和用 Discord 纪元(1420070400000,2015-01-01)会解出相差好几年的时间。所以解析前一定要选对来源。

这些位移和掩码运算,我习惯直接丢给 /zh/t/snowflake-id-decoder/ 来做。它内置了 Twitter 和 Discord 纪元预设,也允许填自定义纪元和位宽,对应自研或 Sonyflake 这类非标准方案。

为什么必须用 BigInt

如果你打算自己写解析代码,有个细节绕不过去:不能用 parseIntNumber

一个 64 位雪花 ID 最大能到约 1.8e19,而 JavaScript 的安全整数上限是 2^53,约 9e15。一旦数字超过这个界,Number 会悄悄把低位四舍五入,结果就是机器号和序列号被算错,而你完全看不出哪里出了问题。正确做法是把原始十进制字符串交给 BigInt,所有位移和掩码都在 BigInt 上做,只在最后把约 13 位的毫秒值收窄成普通 Number(这个值稳稳落在安全范围内)。

雪花 ID 的常见用途

把时间戳从 ID 里读出来,实际能解决不少问题。比如判断一个 Discord 账号的真实注册时间:复制账号 ID,选 Discord 纪元一解,创建时刻精确到毫秒,解出「三分钟前」的多半是小号。再比如排查雪花主键表里顺序错乱的行,把两个可疑 ID 分别解码,如果某个 ID 带着明显错误的时间,基本可以锁定是某台机器时钟漂移了,这是分布式 ID 方案最典型的故障。

雪花本质上是把「时间」嵌进了主键。理解了它的结构,你不光能解读 ID,也能更自信地设计自己的分布式 ID 方案。


Made by Toolora · Updated 2026-06-13