Java的ID生成策略

uuid:标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有5种方式生成UUID

优点:代码简单,生成ID的性能好,全球唯一。

缺点:无序,存储空间大,传输数据量大,查询的时候查询效率低。

数据库序列自增:这个优点就是简单,ID有序。

缺点:分布式和数据迁移的时候就不行了。

Twitter的snowflake算法:

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0,具体的感兴趣的可以去百度一下。

优点:毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。

不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。

可以根据自身业务特性分配bit位,非常灵活。

缺点:强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。

Redis生成ID:1.redis是单线程的,可以用Redis的原子操作 INCR和INCRBY来实现。这样也是灵活方便,性能优于数据库,有序,可以自行设置增加的步长。

2.知道redis的EVAL,EVALSHA命令

原理

利用redis的lua脚本执行功能,在每个节点上通过lua脚本生成唯一ID。

生成的ID是64位的:

使用41 bit来存放时间,精确到毫秒,可以使用41年。

使用12 bit来存放逻辑分片ID,最大分片ID是4095

使用10 bit来存放自增长ID,意味着每个节点,每毫秒最多可以生成1024个ID

比如GTM时间 Fri Mar 13 10:00:00 CST 2015 ,它的距1970年的毫秒数是 1426212000000,假定分片ID是53,自增长序列是4,则生成的ID是:

5981966696448054276 = 1426212000000 << 22 + 53 << 10 + 41

redis提供了TIME命令,可以取得redis服务器上的秒数和微秒数。因些lua脚本返回的是一个四元组。

second, microSecond, partition, seq

客户端要自己处理,生成最终ID。

((second * 1000 + microSecond / 1000) << (12 + 10)) + (shardId << 10) + seq;

当然平时一些小的项目生成不随机的方法还有很多简单的例如:

public static String getRandomChars(Integer length) {

String str = "";

Random random = new Random();

for (int i = 0; i < length; i++) {

boolean b = random.nextBoolean();

if (b) { // 字符串

str += (char) (65 + random.nextInt(26));// 取得大写字母

} else { // 数字

str += String.valueOf(random.nextInt(10));

}

}

return str;

}

当然还有很多生成ID的方式,我只是简单的介绍一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值