介绍几种常见的分布式ID生成策略

329 阅读5分钟

在分布式系统中,生成全局唯一ID是核心需求之一,尤其在微服务、分库分表等场景下。以下是几种主流分布式ID生成方案的原理、优缺点及适用场景的详细分析:


1. UUID

  • 原理:基于时间、节点信息、随机数生成128位唯一标识符(如 550e8400-e29b-41d4-a716-446655440000)。
  • 优点
    • 完全分布式,无需中心节点。
    • 生成速度快,无网络开销。
  • 缺点
    • 无序性导致数据库插入性能低(B+树分裂)。
    • 存储空间大(36字符),可读性差。
  • 适用场景:日志跟踪、临时标识等无需有序性的场景。

2. 数据库自增ID

  • 原理:利用数据库自增主键(AUTO_INCREMENT)生成唯一ID。
  • 扩展方案
    • 分库分表:设置不同起始值和步长(如DB1:1,4,7…,DB2:2,5,8…)。
  • 优点
    • 绝对有序,适合范围查询。
    • 实现简单,无需额外组件。
  • 缺点
    • 扩展性差,新增节点需重新规划步长。
    • 数据库压力大,存在性能瓶颈。
  • 适用场景:小规模系统,ID需求稳定且无需频繁扩容。

3. Redis生成ID

  • 原理:利用Redis的 INCRINCRBY 命令生成递增ID。
  • 优化方案
    • 批量预取:一次获取ID段(如1~1000)缓存在本地。
  • 优点
    • 性能高(10万+/秒),优于数据库。
    • 支持分布式环境。
  • 缺点
    • 需处理Redis持久化问题(宕机可能导致ID重复)。
    • 集群模式下需协调多节点ID分配。
  • 适用场景:高并发但允许短暂ID不连续的场景(如秒杀订单)。

4. Snowflake算法

  • 原理:64位ID = 时间戳(41bit) + 机器ID(10bit) + 序列号(12bit)。
    • 示例1629123456789(时间) + 5(机器) + 4095(序列)= 541763281234567895
  • 优点
    • 高性能(单机每秒26万+),ID有序。
    • 去中心化,无单点故障。
  • 缺点
    • 依赖系统时钟,时钟回拨会导致ID重复。
    • 机器ID需手动分配(ZooKeeper/配置中心)。
  • 改进方案
    • 美团Leaf:解决时钟回拨,支持号段模式。
    • 百度UidGenerator:优化时间戳分配策略。
  • 适用场景:大规模分布式系统(如电商订单、IM消息ID)。

5. 号段模式(Segment,比较常用)

  • 原理:从数据库批量获取ID段(如1~1000),缓存在本地逐步分配。
  • 流程
    1. 业务服务从数据库加载号段(update id_generator set max_id=max_id+1000)。
    2. 本地内存分配ID,号段耗尽后重新获取。
  • 优点
    • 减少数据库访问(TPS从千级降至个位)。
    • 支持容灾,本地号段未用完时宕机不影响。
  • 缺点
    • ID不连续(号段耗尽时跳跃)。
    • 需解决数据库更新的并发控制(乐观锁)。
  • 适用场景:中等并发,允许ID不连续的业务(如用户ID生成)。
  • 举例
CREATE TABLE id_generator ( id int(10) NOT NULL, max_id bigint(20) NOT NULL COMMENT '当前最大id', step int(20) NOT NULL COMMENT '号段的布长', biz_type int(20) NOT NULL COMMENT '业务类型', version int(20) NOT NULL COMMENT '版本号', PRIMARY KEY (`id`) ),id biz_type max_id step version 1 101 1000 2000 0 等这批号段ID用完,再次向数据库申请新号段,对max_id字段做一次update操作,update max_id= max_id + step,update成功则说明新号段获取成功,新的号段范围是(max_id ,max_id +step]。 update id_generator set max_id = #{max_id+step}, version = version + 1 where version = # {version} and biz_type = XXX 由于多业务端可能同时操作,所以采用版本号version乐观锁方式更新,这种分布式ID生成方式不强依赖于数据库,不会频繁的访问数据库,对数据库的压力小很多。

6. 其他方案

  • ZooKeeper顺序节点
    • 利用ZooKeeper的持久顺序节点生成全局有序ID(如 /order/0000000001)。
    • 缺点:性能低(每秒千级),不适合高并发。
  • MongoDB ObjectId
    • 12字节 = 时间戳(4) + 机器ID(3) + PID(2) + 计数器(3)。
    • 优点:轻量级,内置生成。
  • 云服务方案
    • AWS DynamoDB的全局唯一ID,阿里云分布式ID服务。
    • 优点:免运维,高可用。

对比总结

方案有序性性能扩展性缺点适用场景
UUID极高无限无序、存储大日志、临时标识
数据库自增有序扩展困难、性能瓶颈小规模系统
Redis有序依赖Redis持久化高并发订单
Snowflake有序极高时钟回拨问题、机器ID管理大规模分布式系统(订单)
号段模式局部有序ID不连续、需维护号段表用户ID、配置项

选型建议

  • 追求极致性能与有序性:选Snowflake或其改进版(如Leaf-Snowflake)。
  • 高并发允许ID跳跃:Redis或号段模式。
  • 简单快速无依赖:UUID(但需接受无序性)。
  • 云环境优先:使用云厂商提供的托管服务(如AWS Global ID)。

合理选择分布式ID方案,可显著提升系统的扩展性与稳定性,支撑千万级甚至亿级数据场景。