课堂目标

  1. 了解雪花算法
  2. 组成结构
  3. 计算原理
  4. 时钟回拨

一、什么是雪花算法

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

缺点:

  1. 存储空间大:36字符 vs 雪花算法的8字节数字
  2. 无序性影响数据库索引性能(B+树分裂),分裂概率很大
  3. 无法保证时序:虽然加了日期前缀,但整体仍无序
  4. 可读性差:长字符串不如数字直观
  • 最早的做法:

    年+月 +日 +时+分+秒 +自增加 +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个主键

image-20250929111142147

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

image-20250929114420605

四、分布式主键算法:

1、移位运算

直接移动二进制数据在存储空间的位置

image-20250929143306756

image-20250929154513359

image-20250929154605099

五、雪花算法的问题

**时钟回拨:**时间不准确了(一般用NTP服务器校时)

导致的问题:在同一毫秒,同一个机房,同一个机器,导致重复生成主键

12:00:00 001 (走快了1秒)

11:59:59 docker stop

12:00:00 001 docker run

20250930 120001 000 00001 00001 000000000001

image-20250929144507974

解决办法:

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