分布式全局唯一 ID 生成

如何设计一个分布式 ID 生成器(Distributed ID Generator),并保证 ID 按时间粗略有序?
应用场景⌗
各种业务账号订单 ID, 保证幂等的消息 ID 等均需要全局唯一
需求⌗
- 全局唯一(unique)
- 按照时间粗略有序(sortable by time)
- 尽可能短
- 部署简单轻量
方案评估⌗
MongoDB ObjectID⌗
优点⌗
- 多个实例生成 ID 没有依赖关系, 天然分布式高可用
- 高位为时间戳, 本身有序
缺点⌗
- 太长, 12 字节(96 位)
Snowflake⌗
优点⌗
- 64 位, 比较短
- 高位为时间戳, 本身有序
- 分布式高可用
缺点⌗
- 需要额外部署 ZooKeeper 和 Snowflake 服务
DB Ticket Servers⌗
例如 Flickr
利用 mysql 集群
不同的 mysql 服务使用不同步长
优点⌗
- 部署简单, 扩展扩容方便
缺点⌗
- 需要部署管理多台服务器, 单台服务器会变成系统单点
- 多实例生成 ID 并不是严格递增
Instagram pg⌗
和 snowflake 原理相似, 但是只依赖 pg 比较简单
https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c
选择一个开始时间作为 epoch 开始
ID 组成 [41][13][10]
- 高 41 位为当前时间 - epoch 开始 毫秒数
- 中间 13 位为分片 ID
- 低 10 位为递增 ID % 1024
使用 pg 实现:
测试:
原理使用 go 语言简单实现:
优点⌗
- 部署简单, 扩容方便, 初期可在同一 pg 里面使用多个 schema
- 使用时间戳 - 初始时间作为高位, 比直接用时间戳能够使用更多时长
参考资料⌗
Read other posts