分布式算法(六):雪花算法(Snowflake),分布式系统的全局唯一ID生成方案

在分库分表、微服务等分布式场景中,传统单库自增主键无法保证全局唯一性(多库 / 多表会出现 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不同。

分步拆解

  1. 取时间戳:比如现在是“2024-05-20 13:14:00.001”,把这个时间转换成一个数字(相对于某个固定时间点的毫秒数),作为第一块积木;
  2. 拿机器ID:假设当前服务器的ID是“5”,作为第二块积木(提前给每台服务器分配唯一ID,避免冲突);
  3. 编序列号:如果这台服务器在“001毫秒”内已经生成了2个ID,那这次的序列号就是“3”,作为第三块积木;
  4. 拼接:把“时间戳数字 + 机器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也一样~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TracyCoder123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值