一、背景与需求分析

在传统单机系统中,我们常使用数据库自增主键作为数据ID。但在分布式、分库分表环境下,自增ID无法保证全局唯一,因此必须引入分布式ID生成系统。业务系统对ID生成系统提出了以下核心要求:

1.1 基本要求

  • 全局唯一性:绝对不能出现重复ID。

  • 趋势递增:保证ID单调递增,有利于数据库索引性能。

  • 信息安全:避免ID连续,防止被恶意推测业务量。

1.2 系统要求

  • 高可用性:可用性需达到5个9(99.999%)。

  • 低延迟:平均延迟和TP999延迟都要尽可能低。

  • 高QPS:支持高并发请求。


二、常见分布式ID方案对比

2.1 UUID

  • 优点:本地生成,性能极高。

  • 缺点

    • 长度过长(36位字符串),存储不便。

    • 无序性导致数据库索引性能下降。

    • 基于MAC地址的生成方式可能泄露隐私。

2.2 雪花算法(Snowflake)及其衍生

Snowflake算法将64位划分为:

  • 1位符号位(始终为0)

  • 41位时间戳(毫秒级,可用69年)

  • 10位机器ID(可表示1024个节点)

  • 12位序列号(每毫秒生成4096个ID)

  • 优点

    • 趋势递增,性能高。

    • 不依赖第三方系统。

    • 灵活可定制。

  • 缺点

    • 强依赖机器时钟,时钟回拨会导致ID重复。

2.3 数据库生成方案

通过数据库自增ID实现,可设置步长和初始值支持多机部署。

  • 优点:简单、递增、存储空间小。

  • 缺点

    • 并发能力有限。

    • 存在单点故障。

    • 每次获取需访问数据库,压力大。

2.4 Redis生成方案

利用INCR命令实现原子递增。

  • 优点:性能好,有序递增。

  • 缺点:持久化可能丢失数据,导致ID重复。


三、美团Leaf方案详解

美团Leaf提供了两种方案:Leaf-segment和Leaf-snowflake,分别针对不同场景优化。

3.1 Leaf-segment数据库方案

通过批量获取号段(segment)减轻数据库压力。

数据库表设计(见文档Page 5表格):
字段名 类型 说明
biz_tag varchar(128) 业务标识
max_id bigint 当前最大ID
step int 号段长度
description varchar(256) 描述
update_time timestamp 更新时间
工作流程:
  1. 服务从数据库获取一个号段(如1000个ID)。

  2. 号段使用完后,再请求下一个号段。

  3. 数据库更新max_id为新的最大值。

双Buffer优化:
  • 当前号段使用至10%时,异步加载下一个号段。

  • 避免号段用完时阻塞请求,降低TP999延迟。

高可用容灾:
  • 一主两从,分机房部署。

  • 使用DBProxy等中间件实现主从切换。

  • 号段缓存机制确保即使DB宕机,服务仍可短暂运行。

3.2 Leaf-snowflake方案

基于Snowflake算法,通过ZooKeeper自动分配workerID,并解决时钟回拨问题。

弱依赖ZooKeeper:
  • 本地文件系统缓存workerID,ZooKeeper故障时仍可启动。

时钟回拨处理:
  • 启动时检查系统时间是否准确。

  • 运行中定期上报时间至ZooKeeper。

  • 当时钟回拨时,采取等待、报错或摘除节点等策略。


四、tulingmall-unqid实战实现

在电商项目中,我们基于美团Leaf进行了定制化改造。

4.1 移除Leaf-snowflake

由于项目未部署ZooKeeper且不考虑竞对分析,我们移除了Leaf-snowflake部分,仅保留Leaf-segment。

4.2 支持批量获取ID

在订单场景中,一个订单对应多个订单详情,需要一次性生成多个ID。我们改造了Leaf,新增批量获取ID接口,每次最多支持5000个ID。

核心改造:
  • 新增batchGetIds方法,避免多次网络调用。

  • 保证ID全局唯一且趋势递增。

4.3 无状态服务设计

tulingmall-unqid为无状态服务,可轻松扩展集群,实现高可用和高性能。


五、总结与选型建议

方案 优点 缺点 适用场景
UUID 本地生成,性能高 无序,存储长,不安全 临时标识、非数据库主键
Snowflake 趋势递增,性能好 依赖时钟,时钟回拨问题 分布式系统,对递增有要求
数据库生成 简单,递增 并发低,有单点风险 小规模系统
Redis生成 性能好,递增 可能丢失数据 可接受少量ID重复的场景
Leaf-segment 高性能,高可用,支持批量 ID可计算,不够随机 电商、金融等大数据量场景
Leaf-snowflake 随机性好,高可用 依赖ZooKeeper,时钟问题复杂 对安全性要求高的场景

在实际项目中,应根据业务规模、安全要求和运维成本综合考虑。对于电商系统,推荐使用Leaf-segment方案,并结合批量获取优化,以支撑高并发订单场景。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐