分布式ID生成方案小结

几乎所有的系统都存在生成唯一ID的需求,如用户ID、账单ID等,由于系统通常是分布式架构,因而需要有合适的分布式ID生成方案。

常见的分布式唯一ID方法有(欢迎补充):

  • 时间戳
  • 数据库自增ID
  • UUID
  • 放号系统
  • 类snowflake

一、时间戳

原理: 使用直接使用时间戳毫秒值或微秒值作为ID

缺点: 每个时间单位只能生成一个ID, 在分布式架构中不好保证唯一性。

适用场景: 一般很少适用这种方案

二、数据库自增ID

原理: 基于MySQL等数据库的auto_inscrement功能

优势: 实现简单(数据库自带功能),生成的ID单调递增,保证全局唯一;ID长度灵活

缺点: 存储性能上限(MySQL性能), 对数据库重度依赖,一旦数据库宕机则无法生产继续生成ID。

三、UUID

原理: 多个版本,大致原理是 时间戳+机器ID+CPU时钟+随机数。 通过CPU时钟保证本地唯一,通过机器ID+CPU时钟保证全局唯一

优势: 全局唯一,本地生成,没有性能上限

缺点: 生成ID过长(32位16进制字符),不是单调递增

四、放号系统

原理: 通常是基于数据库自增ID的方案改造,只是每次批量获取一个号段,提升了性能。

优势: 和”数据库自增ID“方案类似

缺点: 同样仍然有性能上限,依赖数据库的可用性。数据库主备切换时可能发生ID冲突。存储耗时尖刺(更新DB时延时高)。因为号段通常是定长,拓展性差,对流量波动大的场景不太适用。

参考: https://tech.meituan.com/2019/03/07/open-source-project-leaf.html

升级

放号系统可以升级多个变种,比如采用多个数据库(通过数据库实例ID+数据库自增ID), 在ID消耗完之前(比如消耗了50%)就预申请号段等方案。

五、类snowflake算法方案

原理: 时间戳+机器ID+序列号

优势: uint64型,全局唯一,单调递增,本地生成性能高,每秒能生成的ID较多。

缺点: 需要解决三大问题(增加了复杂度)

三大问题

时间回拨

时间回拨问题的几种解决方案:

  1. 直接抛异常(体验不太好)
  2. 采用历史时间(需要维护历史时间,重启时异常?)
  3. 多时间线(如果多次回拨仍然不能继续放号)

机器ID的分配和回收

机器ID的分配:

  1. 手动配置
  2. 取IP地址的hash值(比较适用于IP地址hash值不冲突的场景)
  3. 引入其他系统维护机器ID

机器ID的上限

snowflake算法使用10bit存储机器,所以机器ID的上线是2^10=1024; 不过这一般也能满足业务需要了(只要做好分配和回收)

六、小结

实际业务中,<放号系统>和<类snowflake>两种方案适用的场景较广。 使用时,可以使用具体的场景选择合适的方案。同时,可以结合需要进行优化。

比如:用户ID可以使用<放号系统>生成,订单号等可以使用类snowflake方案来生成。

使用类snowflake方案时,使用哪种方式分配机器ID也可以根据具体的场景选择。 比如机器较少,各个进程配置方便手动配置时,可以采用手动配置的方式; 如果实在集群中,Pods节点的最后8bit肯定不同,Pods自动扩缩容的场景,可以采用IP地址Hash值的方式来生成机器ID。

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
分布式ID生成方案小结
几乎所有的系统都存在生成唯一ID的需求,如用户ID、账单ID等,由于系统通常是分布式架构,因而需要有合适的分布式ID生成方案。
<<上一篇
下一篇>>