面试知识库
进阶

雪花算法原理#

一句话答案#

64 位 ID:1 位符号 + 41 位时间戳(69 年)+ 10 位机器(1024 台)+ 12 位序列(4096/ms),注意时钟回拨问题。

核心要点

结构: 0(符号) | 41位时间戳(69年) | 10位机器(1024台) | 12位序列(4096/ms)

优点: 有序递增 / 高性能 / 不依赖第三方

时钟回拨问题: 机器时钟回拨会生成重复ID → 解决:拒绝/等待/备用机器ID

面试回答(2分钟版)

雪花算法是 Twitter 开源的分布式 ID 生成方案,生成 64 位长整型 ID,结构分四段:1 位符号位固定为 0,41 位时间戳精确到毫秒可用约 69 年,10 位机器标识支持 1024 个节点,12 位序列号支持每毫秒生成 4096 个 ID。这样单机每秒理论上可以产出约 400 万个 ID。它的优势是纯本地生成不依赖第三方服务、性能极高、ID 趋势递增有利于数据库索引。但要注意它只是趋势递增而非全局严格递增,不同机器同一毫秒产生的 ID 可能乱序。最关键的问题是时钟回拨——如果机器时钟发生回调,会生成和之前重复的 ID。常见解决方案有三种:检测到回拨直接拒绝生成抛异常、等待时钟追上后继续、或者切换到备用的 WorkerID。实际项目中 WorkerID 的分配也需要考虑,可以通过 Nacos 配置、数据库分配或 ZooKeeper 自增节点来管理。

追问与易错

追问方向:

  • “为什么 41 位时间戳?够用多久?”→ 41 位毫秒级时间戳可表示 2^41 ≈ 69.7 年,从自定义起始时间算起(如 2020 年),到 2089 年左右才会溢出,足够绝大部分系统使用
  • “WorkerID 怎么分配?”→ 通过 Nacos/ZooKeeper 配置中心分配、数据库表自增分配、或容器环境用 Pod 序号取模,关键是保证全局不重复
  • “序列号 12 位够用吗?”→ 12 位支持每毫秒 4096 个 ID,即单机每秒 409.6 万;如果同一毫秒超过 4096 则等待下一毫秒,绝大部分业务场景足够

易错点:

  • ❌ 雪花算法全局递增——只是趋势递增
  • ❌ 忽略时钟回拨问题