课堂目标
- 了解雪花算法
- 组成结构
- 计算原理
- 时钟回拨
一、什么是雪花算法
https://github.com/beyondfengyu/SnowFlake
**雪花算法(Snowflake)**是 Twitter 在 2010 年开源的分布式
唯一 ID 生成算法,其主要目标是生成 64 位全局唯一、有序、性能高的
** ID**,广泛用于分布式系统中的数据库主键、消息队列 ID 等场景。
二、在哪些地方使用?
分布式项目里面,主键的生成
三、如何生成主键ID
1、单数据库自增
数据库主键:1,2,3,4,... 比如mybatis plus 的 Type.Auto
优点:简单方便
缺点:一旦分库分表
2、UUID
优点:
全局唯一性:UUID本身就能保证全局唯一
无需协调:不需要像雪花算法那样管理worker ID
简单易实现:不依赖中心化的ID分配服务
天然分区分片:包含日期便于按时间分区
长度为 32 或者 36字节
8-4-4-4-12 (32 or 36字节)
550e8400-e29b-41d4-a716-446655440000
缺点:
- 存储空间大:36字符 vs 雪花算法的8字节数字
- 无序性:影响数据库索引性能(B+树分裂),分裂概率很大
- 无法保证时序:虽然加了日期前缀,但整体仍无序
- 可读性差:长字符串不如数字直观
-
最早的做法:
年+月 +日 +时+分+秒 +自增加 +random
3、雪花算法
-
64bit,占用空间小 8个字节
1、最高位 0代表正 1代表负
2、41位代表的时间时间戳(毫秒) 2^41 = 2199023255552
eg. 20251001092010001 41位可以有 (大概 69.7年)3、5位机房
00001
4、5位机器
00001
5、最后的12位序列有4096(0~4095)
意义:在同一毫秒,同一个机房、同一个机器可以生成4096个主键

now() -1970
00001 - 00001 0000000001
00001 - 00002 0000000001
00002 - 00001 0000000001
2^41 - 1 = 2,199,023,255,551(约2.2万亿)
2^10 =1024 x2x2 =4096
同一个毫秒可以生成4096个主键ID
101010
000000 |或运算 说明只要一个是1结果就是1
101010

四、分布式主键算法:
1、移位运算
直接移动二进制数据在存储空间的位置



五、雪花算法的问题
**时钟回拨:**时间不准确了(一般用NTP服务器校时)
导致的问题:在同一毫秒,同一个机房,同一个机器,导致重复生成主键
12:00:00 001 (走快了1秒)
11:59:59 docker stop
12:00:00 001 docker run
20250930 120001 000 00001 00001 000000000001

解决办法:
- 等 Thread.sleep
- 加机器不同的workId
- 捕获ID服务的异常,手动调用
- 重新获取向其他雪花算法微服务去调用
评论