首页 > 业内资讯 > 分布式 Unique ID 的生成方法一览

分布式 Unique ID 的生成方法一览

时间:2016-02-02 | 来源:developerWorks | 阅读:93

话题: developerWorks

- 进程标识(2bytes 16bits):从JMX里搞回来到进程号,搞不到就用进程名的hash或者随机数混过去。


可见,MongoDB的每一个字段设计都比Hibernate的更合理一点,比如时间戳是秒级别的。总长度也降到了12 bytes 96bit,但如果果用64bit长的Long来保存有点不上不下的,只能表达成byte数组或16进制字符串。


另外对Java版的driver在自增序列那里好像有bug。


Twitter的snowflake

snowflake也是一个派号器,基于Thrift的服务,不过不是用redis简单自增,而是类似UUID version1,


只有一个Long 64bit的长度,所以IdWorker紧巴巴的分配成:

- 时间戳(42bit) 自从2012年以来(比那些从1970年算起的会过日子)的毫秒数,能撑139年。
- 自增序列(12bit,最大值4096), 毫秒之内的自增,过了一毫秒会重新置0。
- DataCenter ID (5 bit, 最大值32),配置值。
- Worker ID ( 5 bit, 最大值32),配置值,因为是派号器的id,所以一个数据中心里最多32个派号器就够了,还会在ZK里做下注册。


可见,因为是派号器,把机器标识和进程标识都省出来了,所以能够只用一个Long表达。


但是,这种派号器,client每次只能一个ID,不能批量取,所以额外增加的延时是问题。


可能觉得用原生的Thirft做传输层不够好,snowflake后来又收回去了不对外开源了。


最后问题,能不能不用派号器,又一个Long搞定UUID??

如果当初你的ID一开始类型设为了Long,又不用派号器的话,怎么办?


思路一,压缩其他字段,留足够多的长度来做机器+进程号标识

时间戳是秒级别,1年要24位,两年要25位.....
自增序列,6万QPS要16位,10万要17位...
剩下20-24位,百万分之一到一千六百万分之一的重复率,然后把网卡Mac+进程号拼在一起再hash,取结果32个bit的后面20或24个bit。但假如这个标识字段重复了,后面时间戳和自增序列也很容易重复,不停的重复。


湘ICP备2022002427号-10湘公网安备:43070202000427号
© 2013~2019 haote.com 好特网