分布式ID的主要需求就是保证在分布式的多机器环境下保证id是唯一的。其次是高可用、如果要存在数据库中最高是有序递增并且带有时间信息。
唯一性方案:
uuid:
uuid的底层是一组32位数的16进制数字构成,,生成过程要用到mac地址、时间戳、芯片ID码和随机数等,理论上几亿年都用不完。
return UUID.randomUUID().toString().replace("-","");
业务场景:
我们公司OA系统里面每个人的唯一id就是uuid。实际场景中拿uuid当主键的好处是避免id有序被别人破解。就像我们公司oa里面每个人照片的下载链接后缀参数都是uuid,如果不是uuid而是有序的id会被直接爬取下载。其他业务场景可以拿去当普通资源的兑换码去使用,比如说网站做一些小活动送优惠卷了,可以当作卡券兑换码之类的。
唯一性+有序+时间:
涉及到数据库的方案,一般都是pass。系统都开始用分布式系统了,数据库肯定也集群了,再去使用数据库帮忙有点本末倒置了。
redis方案:
目前公司通过Redis自增命令与时间戳相结合来提供线程安全的分布式唯一标识符生成策略。原理就是通过redis的原子性自增命令(单线程)+时间戳+填充的数字(高位补0、自己填一部分、随机数)组成一个32位的数字。
// 再填充一些时间和其他数字信息
return jedis.incr("id");
业务场景:做订单号,数据库表主键。
zookeeper方案:
通过创建临时节点来完成,不同客户端每次只能一个创建节来获取节点path来得到唯一id。
return zooKeeper.create("/id", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL).substring(3);
业务场景:做订单号,数据库表主键。
雪花算法:
1位符号位+41位时间戳+10位数据机器位+12位毫秒内的序列。机器位是机房id+机房里面服务器id凑的,后面序列是保证1s内多并发。
return ((timestamp - twepoch) << timestampLeftShift) |
(datacenterId << datacenterIdShift) |
(workerId << workerIdShift) |
sequence;
可能还有其他大厂提供的组件,但原理以及涉及的组件和上面方案差不多。
// 4类方案代码
https://gitee.com/mjTree/javaDevelop/tree/master/distributed/分布式ID
贝氏倭狐猴
贝氏倭狐猴????:体长9-11厘米,尾长12-14厘米,体重30克。这个物种具有非常大的前向眼睛,具有很强的夜视功能。上体毛皮呈红棕色,背部的中线有一条黑色条纹延伸至尾部。下体毛皮是奶油色或浅灰色。头部有明显的标记,鼻子上方有一个沉闷的白色斑块,眼睛周围有肉桂环。像其他的倭狐猴一样,有一条长尾巴,耳朵比较大并裸露无毛。
它们出没于潮湿的热带雨林,树栖,群居,通常结对生活在小溪或河边。以水果和虫子为主食。白天躲在树洞中,傍晚时等到日落才会活都,是一种在夜间活动的孤独者。通过树木和低层植被,寻找昆虫、水果、壁虎和变色龙等小型爬行动物。它们主要食物来源是由蛾蜡蝉幼虫产生的含糖分泌物(或称“蜜露”)。由于非法采伐木材造成的栖息地遭到破坏以及农业扩张,该物种有灭绝的危险。
2014年濒危物种红色名录ver3.1——濒危(EN)。