现今分布式 ID 生成主要使用两种方式:Leaf 和 Snowflake。
Leaf 是一个用于生成分布式唯一 ID 的服务,最早由 美团 开源。它的作用和 Snowflake 算法类似:
👉 在分布式系统中,生成全局唯一、高性能、趋势递增的 ID。
在单机系统里,可以用数据库自增 ID:
sql
id = AUTO_INCREMENT
但在分布式系统中会遇到问题:
- 多个服务同时生成 ID → 会冲突
- 数据库成瓶颈 → 扛不住高并发
👉 所以需要一个独立的 ID 生成系统
🔹 Leaf 提供了两种核心方案
1️⃣ 号段模式(Segment 模式)
👉 基于数据库"批量拿号段"
流程:
- Leaf 从数据库拿一段 ID(比如 1000 ~ 2000)
- 在内存中分配这些 ID
- 用完再去数据库拿下一段
优点:
- 性能高(大部分请求不访问数据库)
- 实现简单
- ID 自增(有序)
缺点:
- 依赖数据库
2️⃣ Snowflake 模式
👉 类似 Twitter 的 Snowflake 算法
ID 结构一般是:
时间戳 + 机器ID + 序列号
优点:
- 不依赖数据库
- 高性能
- 分布式天然支持
缺点:
- 时钟回拨问题(需要处理)
🔹 在系统架构里的典型用法:
text
用户下单 → 调用 Leaf → 获取唯一订单ID → 写入数据库
🔹 很多公司使用 Leaf 原因在于:
- 成熟(美团大规模验证)
- 支持双模式(灵活)
- 性能高(QPS 很强)
- 易扩展(服务化)
🔹 在使用方面
- 👉 大多数业务系统:优先用 Leaf 的号段模式
- 👉 超高并发 + 不想依赖数据库:用 Snowflake 算法
🔹 很多公司更偏向 Leaf(号段模式)核心原因就一个:稳定
✅ 优点
- ID 绝对递增(对数据库索引非常友好)
- 没有时钟问题
- 实现简单,容易维护
- 性能也很高(号段缓存)
⚠️ 缺点
- 依赖数据库(但压力很小)
👉 实际上,这种"弱依赖数据库换稳定性"的设计,在工程上很常见。
🔹相比之下 Snowflake
✅ 优点
- 完全去中心化
- 不依赖数据库
- 性能极高(纯内存计算)
❌ 致命坑
👉 时钟回拨问题
比如:
- 服务器时间被 NTP 校准往回调
- 虚拟机时间漂移
会导致:
- ID 重复 ❌
- 或 ID 不递增 ❌
👉 这在金融、订单系统里是不能接受的
🟢 选 Leaf(号段模式)如果:
- 做业务系统(订单、用户、支付)
- 需要 ID 递增
- 更看重稳定性
- 能接受依赖数据库
👉 ✅ 这是最推荐的默认选择
🔵 选 Snowflake 如果:
- QPS 非常高(比如亿级)
- 想完全去中心化
- 能处理时钟问题(比如加保护机制)
- 对 ID 顺序要求没那么严格
"一般优先选择 Leaf 的号段模式,因为它生成的 ID 单调递增且没有时钟回拨问题,更稳定;Snowflake 虽然性能更高且去中心化,但存在时钟回拨风险,适合对顺序性要求不高的高并发场景。"
很多成熟系统会这样做:
👉 双方案兜底
- 主用 Snowflake
- 出现时钟问题 → fallback 到号段模式
或者:
- 不同业务用不同策略(订单 vs 日志)
🔹 总结
👉 稳定优先选 Leaf(号段),极致性能+去中心化才选 Snowflake。
放在"微博"这种场景里:
👉 核心业务(发微博、评论、用户ID)更适合用 Leaf 的号段模式
👉 而不是纯 Snowflake 算法
微博系统有几个关键特点:
1️⃣ 数据量巨大,但更怕"出错"而不是"慢一点"
- 发一条微博 → 必须有唯一 ID
- 评论、点赞 → 也必须唯一
👉 一旦 ID 重复 = 严重线上事故
而 Snowflake 有一个风险:
- ❌ 时钟回拨 → 可能生成重复 ID
👉 在微博这种体量下,这种风险是不能接受的
2️⃣ 时间有序非常重要
微博场景天然依赖时间顺序:
- 时间线(Feed 流)
- 评论排序
- 热门排序(部分依赖 ID)
👉 Leaf 号段模式:
- ✅ ID 单调递增(更稳定)
- ✅ 对数据库索引、分页更友好
3️⃣ 数据库依赖其实不是问题
很多人以为:
"微博这么大,不能依赖数据库"
其实不是这样:
- Leaf 是"批量拿号段"
- 数据库访问频率很低(比如几千次请求才访问一次 DB)
👉 数据库不会成为瓶颈
🔹 那 Snowflake 也可以使用,在微博这种系统里,常见做法是:
🟡 分场景使用
| 场景 | 方案 |
|---|---|
| 微博ID / 评论ID | ✅ Leaf(号段) |
| 日志ID / 埋点ID | ✅ Snowflake |
| 非核心数据 | ✅ Snowflake |
👉 原则:
- 核心数据 → 稳定优先
- 非核心数据 → 性能优先