全局唯一ID生成服务设计

一般在一些支撑大规模复杂业务中,都会有生成全局唯一的业务ID的诉求,本文就此ID生成服务的诉求来展开

业务诉求

在实际业务系统中,一般会对ID生成服务有哪些要求,下面我们简单介绍几点

全局唯一:在限制周内必须保证不能重复
系统高可用:在特殊情况下 尽最大可能保证系统可用
高并发高性能:此类基础服务,支持业务众多,一般调用量都比较大,同时要求性能很高
使用简单:在当下的大环境中一般提供一个RPC服务输出
可读性: 比如是否需要携带业务含义,是否递增,是否需要控制增长步长(指定周期根据首尾值若步长固定则可以推算业务量)等待

设计方案

1、自然递增
2、随机数+重复检验
3、分段组装 把一段ID分成多段,每一段代表不同的含义,如设备 时间等等

实施落地

自然递增

这种方式实现简单在实际业务中应用相对比较少。 实现简单,可以支持一些要求较少的业务,无法携带任何指定含义,且容易被利用推断业务规模等

最简单,风险也最高的实现 启动一台服务器 使用AtomicInteger 的incrementAndGet生成自增ID,单机内存级,性能最好,效率最高,但是这类方式缺点也多例如 每次系统重启之后都要重新开始
基于上面的情况,我们可以考虑,记录下来最后生成的数据,以此作为系统重启初始化的起点。记录的方式有很多种比如不断更新redis的同一个KEY 等,但是这种情况下 记录失败后是快速失败呢还是默认成功呢。这个就要看具体情况而定了,个人倾向于快速失败,默认成功会肯会造成全局不唯一的情况发生。
当然了上面描述的这类的方案的话的性能可能会被本次操作中记录最大生成ID的方式所影响,也有可能会因此降低吞吐量 ,使得支持的瓶颈变大
另外一种方式就是简单粗暴的依赖数据库的自增ID来搞,这种情况100%保证了数据的持久化,但过于依赖数据库,性能和灾备等方面比较差

随机数+重复检验

这种方式是我刚开始在内心吐槽自然递增会有被动暴露业务规则等的一系列不足的时候,思考的一种方式, 简单聊聊此类方案的落地实现设想。看完之后你会发现 设想也就是个设想
分三步走 首先 引擎随机生成一个新的ID ,然后在存储介质如数据库中检查当前ID是否存在,如果存在则重头开始,如果不存在则进度第三步 把生成的ID存储到数据库中ID排他设计,防止系统并发插入同一个ID。
这种系统有个致命的缺点就是要存储所有已生成的有效ID,这就造成了存存ID的数据量过于庞大。以JD商城交易业务为例,我们假设一分钟发生的总交易量为5000单,我们可以计算下一年的总单量为50006024365≈26亿 ,另外同比我们大概预算下物流单量以一旦2件物品两个物流单号来说 ,本年度需要支持的业务量就将近80亿,假如随着业务发展每年的单量翻倍 ,业务上线三年之后,我们的支持的总量将480亿 这么看,这真的不是一个小数字呀。 另外假如我们随机生成一个ID需要1ns,检查一次需要0.1ms 这种性能在我看来绝对是相当好了,但是我们再做一个假设,我们ID的有1000亿的总量 这大概是10位的纯数字组合的极限了吧,在已生成量将近500亿的时候,我们的ID重复率也将近50%了 ,也就是说我们运气不好的时候有可能要检查250亿次,才能生产出一个新的ID ,250亿0.1ms =250WS≈29天 这个性能估计能让任何一个研发人员目瞪口呆了吧 而且这还不算数据量过大之后对存储介质的性能影响
想想也就仅仅存在于想想了,在上面算了一笔账之后,我简直惊呆了,突然意识到,任何时候都要有一颗敬畏的心啊,如上的方案假如真的在某个地方的生产环境运行了,如果没有一些配套的方式来控制ID重复率和已产出ID总量的话,那么随着时间的推移,这无疑是一种灾难。

分段组装

这种方式据我了解,应该在业界使用相对比较广泛比如经典的snowflake算法生成64位的ID,我们先简单聊一下这类设计的思想,我个人感觉这类设计与现在互联网中广泛使用的IP地址类似,均采用分段设计,分层次管理,自上而下,只要高位不同,那地位可以随意组合,基于不同的高位组合出来的ID必然不会相同,利用这一特性,我们可以更为灵活的按需设计。

简单设计一个16位的ID生成器,来支撑QPS 1W TP99 1MS 的一个服务
使用1-3 前三位标记提供服务的集群中的机器所在编码 实际使用10台
使用4-9 中间6位标记作为年度的分钟计数器 3652460=525600
余下10-16 余下6位 使用自增涨格式化000001 单服务提供QPS 1000 使用RateLimit 等限流工具控制系统的流量情况在日常流量的5倍作为阈值即可

每台机器的自增涨均使用该机器的集群分配编号作为启动步长理论上 改设计默认可以支持集群规模为000-999 1000台机器
以最大集群我们可以推断单机增长量为999999/999=1001 单机每分钟 自增涨1000以内就不会重复

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值