P44 分布式 ID 面试必问五大坑
面试题:分布式 ID 生成方案有哪些?生产环境落地有哪些坑?
常见方案回顾
- UUID:本地生成,但无序、太长;
- 数据库自增/号段:MySQL 自增、批量号段(Leaf);
- Redis INCR:原子自增,依赖 Redis;
- Snowflake 雪花算法:时间戳 + 机器 ID + 序列号,趋势递增、高性能;
- 第三方发号服务:美团 Leaf、百度 UidGenerator、滴滴 Tinyid。
五大坑(视频重点)
坑 1:ID 无序导致性能问题
- UUID / 随机 ID 作数据库主键:B+ 树页分裂、索引碎片、插入性能暴跌;
- 解决:用趋势递增 ID(雪花/号段),或业务上别拿 UUID 当主键。
坑 2:雪花算法的时钟回拨
- 服务器 NTP 时钟回拨,可能导致生成的 ID 重复/倒退;
- 解决:
- 短时间回拨:等待(等时钟追上);
- 记录上次生成时间,回拨时拒绝生成或走备用方案(如用 Redis 递增兜底);
- 美团 Leaf 等方案有专门处理。
坑 3:机器 ID 分配与唯一性
- 雪花算法的 10 位机器 ID(5 位机房 + 5 位机器)分配不当会重复,导致 ID 冲突;
- 解决:机器 ID 集中注册(ZK/DB/配置文件),保证全局唯一;集群超过 1024 台要换方案。
坑 4:序列号溢出与并发上限
- 同一毫秒内序列号(12 位,最多 4096 个)溢出;
- 解决:溢出时等待下一毫秒(自旋),或改用更大位宽/多实例分摊;
- 还要注意:不同机器同一毫秒生成相同 ID 的风险,序列号要和机器 ID 协同。
坑 5:ID 可预测性 / 泄露业务信息
- 自增 ID 容易被遍历抓取(订单号、优惠券号),造成数据泄露风险;
- 雪花 ID 带时间戳,能反推生成时间,有时会暴露业务量;
- 解决:对外的 ID 做混淆/加密(如短链编码、HMAC 签名),内部 ID 与外部 ID 分离。
选型建议
- 大多数业务:**号段模式(DB 批量发号)**最稳;
- 高性能、趋势递增:雪花算法 + 时钟回拨保护;
- 高可用分布式:美团 Leaf(号段/雪花可切换)。
一句话总结
分布式 ID 别踩五个坑:无序伤索引、时钟回拨会重复、机器 ID 要唯一、序列号会溢出、ID 可预测泄露信息;选型上号段最稳、雪花要加回拨保护,对外 ID 加密防遍历。