分布式唯一id生成策略

2025年Java面试宝典:
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g 提取码: 9b3g
为什么需要分布式唯一ID?
在分布式系统中,数据库分表、服务多节点部署是常态。如果直接用数据库自增ID,会出现ID冲突问题。比如订单表拆分成10个子表,每个子表从1开始自增,结果就是大量订单的ID重复,查询时根本无法区分。
这时候就需要一个全局唯一且趋势递增的ID生成方案。这个ID不仅要唯一,还要满足高并发、低延迟、易扩展等要求。
常见的生成策略对比
1. UUID
UUID是最简单的方案,本地生成不依赖网络,生成速度快。但缺点也很明显:
- 存储空间大:128位字符串,占用36字节
- 无序性:插入数据库时会导致B+树频繁分裂,影响性能
- 无业务含义:无法体现时间、分库分表等信息
适合临时数据或对性能要求不高的场景。
2. 数据库自增ID
通过集中式数据库生成ID,比如单独建一张表记录自增值。优点是实现简单、ID绝对有序。但缺点更致命:
- 单点故障:数据库挂了整个系统瘫痪
- 性能瓶颈:高并发场景下,每秒生成几万个ID就可能扛不住
可以通过部署多个数据库实例(比如设置不同步长)缓解,但增加了运维复杂度。
3. 雪花算法(Snowflake)

Twitter开源的分布式ID生成算法,核心思想是将64位二进制分成多个字段:
- 1位符号位(固定为0)
- 41位时间戳(毫秒级,可用69年)
- 10位机器ID(最多支持1024个节点)
- 12位序列号(单节点每毫秒生成4096个ID)
优点是性能高、可扩展、ID带时间信息。但需要注意两个问题:
- 机器ID需要手动分配,推荐用ZooKeeper或Redis自动分配
- 依赖系统时钟,如果发生时钟回拨会生成重复ID(可通过记录上次生成时间解决)
4. 号段模式(Segment)
美团开源的Leaf-Segment方案,核心思想是预分配号段:
- 从数据库批量获取一段ID(比如1-1000)
- 内存中分配ID,用完再申请下一段
- 通过双Buffer交替使用提升性能
优点是对数据库压力小,性能高。缺点是实现复杂,且需要维护号段状态。
面试场景如何回答?
如果面试官问:“你们项目用哪种分布式ID方案?”,建议回答雪花算法或号段模式,并解释选择理由。比如:
“我们用的是雪花算法,因为业务需要ID带时间信息,方便按时间归档数据。同时机器ID通过Kubernetes的环境变量自动注入,避免了手动配置的麻烦。针对时钟回拨问题,我们加了异常检测机制,如果回拨超过100ms就直接抛异常,防止数据不一致。”
如果面试官追问:“如果让你设计一个分布式ID系统,要考虑哪些点?”,可以从这些方向展开:
- 唯一性:必须全局唯一
- 有序性:是否要求严格递增
- 吞吐量:每秒生成多少ID
- 可用性:是否容忍短时间不可用
- 扩展性:如何支持机房扩容
最后的小福利
如果大家在准备面试时需要Java面试题库或系统设计资料,可以关注我的推荐:2025年Java面试宝典,覆盖90%的高频考点。
另外,如果需要购买面试鸭会员,可以通过面试鸭返利网找到我,返现25元!用更低成本解锁全站资源,性价比超高~



