目录

分布式系统全局唯一ID生成器

分布式系统全局唯一ID生成器

代码实现示例repo地址

使用场景一般:

  • 分布式系统设计时,数据分片场景下,通常需要一个全局唯一id;

  • 在消息系统中需要消息唯一ID标识来防止消息重复;

  • 多系统打通需要一个全局唯一标识 (如集团各业务线面对不同用户,需要一个全局用户id);

一般有三种方式实现:

  • UUID

    Universally Unique Identifier 是自由软件基金会组织制定的唯一辨识ID生成标准,大多数系统已实现,如微软的GUID实现。

    生成格式如:3d422567-f034-4ab4-b98f-a34fd263d0de。

  • sequence

    使用数据库维护一张映射表,使用主键自增生成唯一ID。

  • SnowFlake

    Twitter实现的算法,使用时间戳+机器分配标识+自增序列组成64位数字ID。

    生成格式如:1292755860950487050

UUID

实现可通过以下方式:

  • google方案:https://github.com/google/uuid

  • linux命令:/usr/bin/uuidgen

优点:性能高,本地生成,无依赖。

缺点:生成格式太长,不适合做数据库主键id,基于mac地址生成算法可能导致mac地址泄漏。

sequece

实现的时候需要注意并发写读,使用事务进行解决。

在冗余服务部署时,可部署多个库表且设置不同step,让每个sequence产生不同id。

可提前进行分配id然后加载到业务中,可减少数据库IO操作,提高性能。

优点:ID单调递增,方便排序,且方案成熟部署简单。

缺点:依赖DB,若为单节点则有性能瓶颈,若为主从架构则需要注意主从一致性问题。

SnowFlake

  • 1位最高位:符号位不使用;

  • 41位时间戳:2^41-1个数字代表69年,所以设置发号起始时间最好为发号器首次运行时间 ;

  • 10位工作机器id:也会分为5位datacenterId和5位workerId ;

  • 12位序列号:2^12-1个数字总共4095,同一毫秒同一机器节点可以并发产生4095个不同Id;

在部署上面,不同机器使用不同DatacenterId(数据中心集群id)和WorkerId (机器节点id),最多可部署1024个节点。

多节点部署时,可使用zookeeper做节点分布式协调进行一致性管理,当出现时钟回拨可由zk来同步时间或摘除节点。

优点:ID呈递增趋势,满足排序场景,不依赖于其他组件且易于维护。

缺点:依赖机器时钟,会因为时钟回拨问题会导致发号重复或不可用,代码实现时采用循环等待下一时钟的方式,可能会有性能问题。

总结

UUID sequence snowflake
描述 集成在标准系统中可简单生成 使用DB自增id实现 根据时间+机器分配标识+自增序列生成
依赖 DB
优点 本地生成性能高 部署简单生成ID单调递增 部署简单生成ID单调递增
缺点 生成号码复杂,很多场景不利于使用 依赖DB有性能问题和重复发号问题号码存在规律会泄露信息 依赖系统时钟,时钟回拨会造成重复发号问题

针对sequence表方式、snowflake方式的缺点,美团leaf给出了更详细的优化方案可以参考,这里就不过多引用,直接查看参考文档。

参考

https://mp.weixin.qq.com/s/XjF_6x7uRzX-gLCdnb5DQQ