唯一ID生成器设计方案

《亿级流量系统架构设计与实战》总结

1. 唯一ID的核心需求

全局唯一性:分布式系统中所有节点生成的ID不可重复。
趋势递增性(可选):ID按时间或序列递增,优化数据库写入性能。
高可用性:服务需7×24小时可用,支持故障自动恢复。
高性能:单节点QPS需达到数万至百万级别。
可扩展性:支持水平扩展以应对业务增长。


2. 单机递增方案
2.1 Redis INCR命令

原理:利用Redis原子操作INCRINCRBY生成单调递增ID。
实现

# 生成ID
redis-cli INCR my_counter

技术细节
集群模式:通过Redis Cluster分片存储多个计数器(如user_id:1, order_id:2)。
持久化:开启AOF或RDB确保重启后ID不丢失。
优点:简单高效,延迟低(毫秒级)。
缺点
• 依赖Redis集群,增加系统复杂度。
• 高并发下可能成为瓶颈(需维护长连接池)。
适用场景:低并发系统或作为其他方案的兜底。


2.2 数据库自增主键

原理:利用关系型数据库(如MySQL)的自增主键特性。
实现

ALTER TABLE user AUTO_INCREMENT = 1000;
INSERT INTO user (name) VALUES ('Alice');

技术细节
分库分表友好性:可通过MOD运算拆分表(如user_id % 1024)。
主从延迟:主从同步可能导致短暂ID不连续。
优点:绝对有序,天然事务支持。
缺点
• 扩展性差,需预分配ID段或频繁修改表结构。
• 高并发写入易成为性能瓶颈。
适用场景:传统单体应用或低并发场景。


3. 分布式递增方案
3.1 Snowflake算法

核心组成

long id = ((timestamp - twepoch) << timestampLeftOffset) 
          | (datacenterId << datacenterIdShift)
          | (machineId << machineIdShift)
          | sequence;

参数说明
timestamp:毫秒级时间戳(41位,支持约69年)。
datacenterId:数据中心ID(5位,支持32个机房)。
machineId:工作机器ID(5位,支持32台机器)。
sequence:序列号(12位,同一毫秒内支持4096个ID)。
技术实现
时钟回拨问题:记录历史时间戳,若发生回拨则抛出异常等待时钟同步。
位分配优化:根据业务需求调整各字段位数(如延长timestamp到42位)。
优点
• 分布式生成,性能高(单机QPS可达百万)。
• ID趋势递增,利于数据库写入。
缺点
• 依赖机器时钟,时钟回拨可能导致ID重复。
• 需手动分配datacenterIdmachineId
适用场景:高并发、需趋势递增的场景(如订单号、消息ID)。


3.2 Leaf(美团分布式ID生成服务)

Leaf-segment方案
原理:预分配ID号段(如1000~1999),客户端批量拉取号段。
架构
Client → Leaf Server(号段分配) → DB(存储号段状态)
优化:支持号段预加载(如提前拉取下一个号段)。

Leaf-snowflake方案
原理:基于Snowflake算法,通过ZooKeeper选举Master节点分配machineId
架构
Client → Leaf Server(Snowflake节点) ← ZooKeeper(协调)
技术细节
号段分配:支持号段长度动态调整(如从1000调整为10000)。
时钟回拨检测:Leaf-snowflake集成Snowflake的时钟回拨处理逻辑。
优点
• 高可用,支持号段和Snowflake双模式切换。
• 支持号段/雪花模式混合部署。
缺点
• 依赖外部存储(如DB/ZooKeeper)。
• 需部署中间件服务。
适用场景:中大规模分布式系统,需兼顾灵活性和高可用性。


4. 其他方案
4.1 UUID

原理:基于MAC地址、时间戳和随机数生成128位唯一标识。
实现

UUID.randomUUID().toString() // 输出类似 "123e4567-e89b-12d3-a456-426614174000"

优点:本地生成,无依赖。
缺点
• 无序导致数据库索引性能下降。
• 存储空间大(16字节)。
适用场景:离线系统或对顺序无要求的场景。

4.2 Redis Hash/Redisson

原理:利用Redis的Hash数据结构生成ID。
实现

HSET my_hash field 1
HINCRBY my_hash field 1

优点:支持原子递增,可扩展多个Hash实例。
缺点:需维护Redis集群,性能低于原生INCR。


5. 方案对比与选型建议
方案全局唯一性趋势递增性能复杂度适用场景
Redis INCR✔️✔️低并发系统
数据库自增✔️✔️传统单体应用
Snowflake✔️✔️极高高并发、需趋势递增的场景
Leaf-segment✔️中大规模分布式系统
Leaf-snowflake✔️✔️极高需混合部署的复杂系统

6. 架构图示
6.1 Snowflake算法架构
Client → Time Service(获取时间戳)
       ↓
     Machine ID(通过配置或ZooKeeper分配)
       ↓
 Sequence Generator(本地计数器)
       ↓
ID合成器 → [timestamp << 22] | [machineId << 17] | [sequence]
6.2 Leaf分布式服务架构
Client → Leaf Client SDK → Leaf Server(HTTP/RPC接口)
       ↑                    ↓
       └─── ZooKeeper(协调Master选举) ────┘

7. 最佳实践
  1. 时钟回拨防御
    • 记录历史时间戳,若检测到回拨则抛出异常等待时钟同步。
    • 使用NTP服务校准时钟,减少回拨概率。
  2. 分库分表友好
    • ID高位分配分片字段(如末尾N位表示分片号)。
  3. 预生成ID池
    • 对高并发场景预加载ID池(如提前生成10万ID缓存在本地)。

通过以上方案对比和技术实现细节,可根据业务场景选择最适合的唯一ID生成策略。对于大多数互联网业务,推荐使用Leaf-snowflake或Snowflake算法,兼顾性能与可用性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值