Prompts-MCP 686 skills · ai / design / design-pattern / framework / fundamentals / habit / lang / tech-selection /mcp/sse
fundamentals fundamentals/distributed-theory/distributed-id.md medium

distributed-id

分布式 ID 算法选型(理论视角)— 雪花算法本地生成但有时钟回拨、号段模式趋势递增依赖 DB、Redis incr 简单、UUID 无序不宜做主键,按是否要有序/是否依赖中心组件取舍。Use when 给分布式系统选全局唯一 ID 算法 / 在雪花/号段/Redis/UUID 间权衡时。

分布式 idid 选型雪花算法时钟回拨号段模式uuid
paths
  • *.java

分布式理论 · 分布式 ID 选型(算法视角)

本条是理论/算法选型视角:在雪花/号段/Redis/UUID 之间按特性取舍。 若你的问题是「分库分表后主键怎么选、为什么不能用 UUID 伤聚簇索引」,那是 DB 主键视角,去 ../../framework/mysql/ops/distributed-id.md(含号段/雪花的 DB 落地细节)。 分工:本条管"选哪种算法及其取舍",那条管"作为 MySQL 主键时的约束与发号器实现",避免重复。

四种算法对比

算法 有序性 依赖 关键问题
雪花算法 Snowflake 趋势递增 无中心,本地生成 时钟回拨会重号,须处理
号段模式 segment 趋势递增、连续 DB 发号 中心 DB,宕机丢一段(可接受)
Redis incr 单调递增 Redis Redis 单点/持久化丢号风险
UUID 无序 36 位随机串,不宜做有序主键

选型速判

要本地高并发生成、无中心依赖   → 雪花(务必处理时钟回拨)
要 ID 连续/可读、能接受中心发号 → 号段模式
量不大、已有 Redis、想简单      → Redis incr
只需全局唯一、不要求有序        → UUID(如 traceId、文件名;别拿来当 DB 主键)

时钟回拨:雪花的头号坑

雪花高位是时间戳,机器时钟被 NTP 校准回拨时会生成更小甚至重复的 ID。处理策略:

回拨幅度小 → 等待时钟追上再发号(阻塞几毫秒)
回拨幅度大 → 直接拒绝发号并告警 / 切换备用 workerId
进阶       → 用百度 uid-generator / 美团 Leaf 等带回拨处理的成熟实现

反例

❌ 拿 UUID 当 MySQL 主键:无序破坏聚簇索引(详见 mysql 那条),且占空间
❌ 自己撸雪花不处理时钟回拨:NTP 一校准就重号,唯一性直接破防
❌ workerId 多机重复(如硬编码/同镜像部署):不同机器生成相同 ID
❌ 单库未分片就上分布式 ID 算法:过度设计,库自增 BIGINT 就够

自检

  • [ ] 按「是否要有序 × 是否依赖中心组件」选算法,不是无脑雪花?
  • [ ] 用雪花时处理了时钟回拨,且 workerId 多机唯一?
  • [ ] UUID 只用在不要求有序的场景,没拿来当有序主键?
  • [ ] 作为 DB 主键的约束已对照 mysql/ops/distributed-id,没在两处重复设计?

相关