跳转至

分布式系统唯一 ID 生成方案

一、要求

全局唯一、趋势递增、高可用、高性能。

二、常见方案

1. UUID

  • 优点:本地生成,无网络开销。
  • 缺点:太长(128 bit)、无序(做主键导致 B+ 树页分裂)、不含业务信息。

2. 数据库自增

  • 优点:简单、有序。
  • 缺点:DB 单点、性能瓶颈、分库分表失效。

3. 数据库号段模式

每次从 DB 取一段 ID(如 1000~2000),内存用完再取下一段。

CREATE TABLE id_segment (
    biz_tag varchar(64),
    max_id bigint,
    step int
);
  • 优点:DB 压力小。
  • 缺点:DB 仍有压力,宕机可能丢一段。

4. 雪花算法(Snowflake)

64 bit:

| 1 bit 符号位 | 41 bit 时间戳 | 10 bit 机器 ID | 12 bit 序列号 |
  • 41 bit 时间戳:可用约 69 年。
  • 10 bit 机器 ID:1024 个节点。
  • 12 bit 序列号:每毫秒 4096 个 ID。

单机 QPS 可达百万。

问题:时钟回拨。机器时间回退可能生成重复 ID。解决: - 检测时钟回拨,小幅度等待。 - 大幅度报错。

5. Redis INCR

INCR biz:orderId
  • 优点:原子、有序。
  • 缺点:依赖 Redis 持久化和高可用。

6. Leaf(美团)、UidGenerator(百度)

开源方案,结合号段 + 雪花,解决时钟回拨、Worker ID 分配。

三、方案选择

方案 有序 性能 可用性
UUID 极高
DB 自增
号段
雪花 趋势递增 极高 高(时钟问题)
Redis 递增

高频追问

  • 为什么 MySQL 自增 ID 在分库分表后不能用?每个库都从 1 开始会重复。
  • 雪花算法的机器 ID 怎么分配?注册中心 / K8s StatefulSet 序号 / 配置。