分布式系统唯一 ID 生成方案¶
一、要求¶
全局唯一、趋势递增、高可用、高性能。
二、常见方案¶
1. UUID¶
- 优点:本地生成,无网络开销。
- 缺点:太长(128 bit)、无序(做主键导致 B+ 树页分裂)、不含业务信息。
2. 数据库自增¶
- 优点:简单、有序。
- 缺点:DB 单点、性能瓶颈、分库分表失效。
3. 数据库号段模式¶
每次从 DB 取一段 ID(如 1000~2000),内存用完再取下一段。
- 优点:DB 压力小。
- 缺点:DB 仍有压力,宕机可能丢一段。
4. 雪花算法(Snowflake)¶
64 bit:
- 41 bit 时间戳:可用约 69 年。
- 10 bit 机器 ID:1024 个节点。
- 12 bit 序列号:每毫秒 4096 个 ID。
单机 QPS 可达百万。
问题:时钟回拨。机器时间回退可能生成重复 ID。解决: - 检测时钟回拨,小幅度等待。 - 大幅度报错。
5. Redis INCR¶
- 优点:原子、有序。
- 缺点:依赖 Redis 持久化和高可用。
6. Leaf(美团)、UidGenerator(百度)¶
开源方案,结合号段 + 雪花,解决时钟回拨、Worker ID 分配。
三、方案选择¶
| 方案 | 有序 | 性能 | 可用性 |
|---|---|---|---|
| UUID | ❌ | 极高 | 高 |
| DB 自增 | ✅ | 低 | 低 |
| 号段 | ✅ | 高 | 中 |
| 雪花 | 趋势递增 | 极高 | 高(时钟问题) |
| Redis | 递增 | 高 | 高 |
高频追问
- 为什么 MySQL 自增 ID 在分库分表后不能用?每个库都从 1 开始会重复。
- 雪花算法的机器 ID 怎么分配?注册中心 / K8s StatefulSet 序号 / 配置。