在分库分表、微服务等分布式场景中,传统单库自增主键无法保证全局唯一性(多库 / 多表会出现 ID 重复),而雪花算法(Snowflake)是解决这一问题的经典方案 —— 它能在分布式环境下生成有序、高效、无重复的 64 位 Long 型 ID,无需依赖数据库等第三方组件,广泛应用于 Java 后端、大数据等领域。
雪花算法的核心:用“时间+机器+序号”拼出唯一ID,就像给每个数据分配一张“全球唯一身份证”,既不重复,又能按时间排序。
先看最终效果:雪花ID长啥样?
雪花算法生成的是 64位数字(Java里的long类型),比如:1305253469759057920
这个数字看着复杂,但其实是“3段关键信息”拼接出来的,就像身份证号(省份+城市+个人编号)一样有规律。
核心逻辑:3段信息拼出唯一ID
把64位ID想象成“3块积木”,每块积木负责一个“去重维度”,三者结合确保全球唯一:
- 积木拆解:
┌─────────────────┬────────────┬─────────────────────┐
│ 时间戳(41位) │ 机器ID(10位) │ 序列号(12位) │
├─────────────────┼────────────┼─────────────────────┤
│ 记录生成时间 │ 标识哪台机器 │ 同一时间的序号 │
│ (按时间递增) │ (避免跨机器重复) │ (避免同一机器同一时间重复) │
└─────────────────┴────────────┴─────────────────────┘
每块积木的作用
| 积木名称 | 通俗作用 | 举个例子(生活化类比) |
|---|---|---|
| 时间戳段 | 记录“生成时间”(精确到毫秒) | 比如“2024-05-20 13:14:00.001” |
| 机器ID段 | 标识“哪台服务器生成的” | 比如“服务器A”“服务器B” |
| 序列号段 | 同一毫秒内的“顺序编号” | 同一秒内服务器A生成的第1、2、3个ID |
为什么这样拼就不会重复?
就像“班级+学号”唯一标识学生:
- 不同时间生成的ID:时间戳段不同 → 整体ID不同;
- 同一时间不同机器:机器ID段不同 → 整体ID不同;
- 同一时间同一机器:序列号段递增 → 整体ID不同。
分步拆解
- 取时间戳:比如现在是“2024-05-20 13:14:00.001”,把这个时间转换成一个数字(相对于某个固定时间点的毫秒数),作为第一块积木;
- 拿机器ID:假设当前服务器的ID是“5”,作为第二块积木(提前给每台服务器分配唯一ID,避免冲突);
- 编序列号:如果这台服务器在“001毫秒”内已经生成了2个ID,那这次的序列号就是“3”,作为第三块积木;
- 拼接:把“时间戳数字 + 机器ID5 + 序列号3”拼起来,就是一个唯一的雪花ID。
关键问题:3个核心疑问解答
-
为什么ID是有序的?
因为“时间戳段”是按时间递增的——后生成的ID,时间戳数字更大,所以整体ID也更大,自然有序。
(就像按“年份+序号”排序的发票,越晚开的发票号越大) -
同一毫秒能生成多少个ID?
序列号段有12位,最多能表示2^12 = 4096个数字(0-4095)。
也就是说:同一台服务器,同一毫秒内最多能生成4096个不重复ID,完全够应对高并发(比如秒杀场景)。 -
时钟回拨会导致重复吗?
时钟回拨:服务器时间突然调到之前的时间(比如NTP同步出错)。
解决方案:如果当前时间比上一次生成ID的时间还早,就“等一等”,直到时间超过上一次,再生成ID——避免用旧时间+相同序列号导致重复。
雪花算法的核心优势
“时间定先后,机器分你我,序号不重复”——用3段简单信息,低成本实现分布式环境下的唯一有序ID,不用依赖数据库、Redis等外部工具,生成速度还超快(单机每秒百万级)。
如果还是没懂,记住这个类比:
- 雪花ID = 「出生年份(时间戳)」 + 「籍贯(机器ID)」 + 「身份证号(序列号)」
全球范围内,没有人的这三组信息完全相同,雪花ID也一样~
191

被折叠的 条评论
为什么被折叠?



