几乎所有的系统都存在生成唯一ID的需求,如用户ID、账单ID等,由于系统通常是分布式架构,因而需要有合适的分布式ID生成方案。
常见的分布式唯一ID方法有(欢迎补充):
原理: 使用直接使用时间戳毫秒值或微秒值作为ID
缺点: 每个时间单位只能生成一个ID, 在分布式架构中不好保证唯一性。
适用场景: 一般很少适用这种方案
原理: 基于MySQL等数据库的auto_inscrement功能
优势: 实现简单(数据库自带功能),生成的ID单调递增,保证全局唯一;ID长度灵活
缺点: 存储性能上限(MySQL性能), 对数据库重度依赖,一旦数据库宕机则无法生产继续生成ID。
原理: 多个版本,大致原理是 时间戳+机器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%)就预申请号段等方案。
原理: 时间戳+机器ID+序列号
优势: uint64型,全局唯一,单调递增,本地生成性能高,每秒能生成的ID较多。
缺点: 需要解决三大问题(增加了复杂度)
时间回拨问题的几种解决方案:
机器ID的分配:
snowflake算法使用10bit存储机器,所以机器ID的上线是2^10=1024; 不过这一般也能满足业务需要了(只要做好分配和回收)
实际业务中,<放号系统>和<类snowflake>两种方案适用的场景较广。 使用时,可以使用具体的场景选择合适的方案。同时,可以结合需要进行优化。
比如:用户ID可以使用<放号系统>生成,订单号等可以使用类snowflake方案来生成。
使用类snowflake方案时,使用哪种方式分配机器ID也可以根据具体的场景选择。 比如机器较少,各个进程配置方便手动配置时,可以采用手动配置的方式; 如果实在集群中,Pods节点的最后8bit肯定不同,Pods自动扩缩容的场景,可以采用IP地址Hash值的方式来生成机器ID。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。