分布式id生成器

id生成器在工作中比较常用,是为了有一个全局唯一性的值。

最早接触的是uuid,因为使用方便,java1.5以后的util包里就有声称uuid的函数
UUID由当前时间(纳秒级),机器的ieee识别码(网卡mac)和随机树来生成,重复几率极低,现有的工程数据级别根本不用考虑重复,当然我不知道基因工程里面对细胞等的解析会不会超过这个数量级。
缺点是太长了,online id生成器上生成一个感受下
810d0bca-d84c-4667-93a4-5c12c9f83ddf
不太方便进db,占用的空间太大,而且是随机无序的,作为key不利于数据库分页

后来做项目用到了mongodb的object_id,占用12字节
4字节:UNIX时间戳
3字节:表示运行MongoDB的机器
2字节:表示生成此_id的进程
3字节:由一个随机数开始的计数器生成的值
长度大概是这个级别5d104f29bf1144fe800ba32d,比uuid的优点在于由于前4字节是时间戳,所以数据相对连续,问题也在于长度过长,并且需要有一个维护mongodb的开销

最近接触到了snowflake算法,是twitter发明出来的
分布式id生成器

网上找的比较通用的一张图。
41bit的时间是ms级的,能够支持69.7年
10bit的工作id其实是不够用的,对于大型项目,即使拆分成了微服务,1023个机器id是不够的,所以实际实现中会压缩后面的12bit***或者直接加大总长度。一般采用的是减少***,22bit的总量其实可以保证1ms内产生2^22-1即几十万级别的数据量,所以可以支撑秒级亿级别的数据量。绝对是够用的,双11的淘宝秒级也就几百万并发的量不用担心。

其实机器id的位数问题可以通过将id生成器作为服务的方式给解决,不是依靠服务本身,这样就能确保机器id够用了。不过这同时会引入一个问题,就是机器时间校准,为了业务服务本身可以通过时间戳来判断先后比如日志id,这个时间戳用的应该是请求id的时间戳,这就有可能导致不同机器过来的请求在同一时间生成了,这样随机数生成重复的机率就变大了。