简单实用!利用Redis轻松实现高并发全局ID生成器

发布时间:2025-05-16 17:27:11 作者:益华网络 来源:undefined 浏览量(2) 点赞(3)
摘要:Redis作为高性能的KV数据库,并且操作还是原子性的,所以用来做支持高并发的发号器十分合适。 本文给大家介绍3种常见的全局ID生成方式。 1、全局递增ID 目标:一直递增的全局ID。 /** * 一直递增的全局id * * @param redisTemplate red

Redis作为高性能的KV数据库,并且操作还是原子性的,所以用来做支持高并发的发号器十分合适。

本文给大家介绍3种常见的全局ID生成方式。

1、全局递增ID

目标:一直递增的全局ID。

/**

* 一直递增的全局id

*

* @param redisTemplate redis客户端对象

* @param busId 业务id,可以按需配置

* @param step 步长,即每次递增的间隔

*/

public static String getNo(RedisTemplate redisTemplate, String busId, int step) {

//保存redis中的key,注意不要重复

String redisKey = "uniqueNo_";

//利用increment即redis原生incrBy命令的原子性特性生成递增的序列号

Long increment = redisTemplate.opsForValue().increment(redisKey, step);

if (increment == null) {

throw new RuntimeException("redis命令执行失败");

}

//业务id+递增id,如果需要纯数字,去掉业务id即可

return busId + increment;

}

2、以天为分割的全局ID

目标:生成格式为 yyyyMMdd + 递增序列号的全局ID。

/**

* 以天为间隔的递增序列号

* @param redisTemplate redis客户端对象

* @param busId 业务id,可以按需配置

* @param step 步长,即每次递增的间隔

*/

public static String getNo(RedisTemplate redisTemplate, String busId, int step) {

//当天日期,比如20221226

String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

//保存redis中的key,注意不要重复

String redisKey = "uniqueNo_" + date;

//利用increment即redis原生incrBy命令的原子性特性生成递增的序列号

Long increment = redisTemplate.opsForValue().increment(redisKey, step);

if (increment == null) {

throw new RuntimeException("redis命令执行失败");

}

if (step == increment.intValue()) {

//首次执行时,给redisKey设置ttl,第二天这个key就可以被redis自动删除

redisTemplate.expire(redisKey, 25, TimeUnit.HOURS);

}

//组合 20221226 + 业务id + 0001(可以根据需要自由调整序列号的长度)

return date + busId + String.format("%04d", increment);

}

3、批量获取ID

有时我们需要批量的获取递增ID,比如给一批订单号设置ID。

/**

* 批量获取id

*

* @param redisTemplate redis客户端对象

* @param busId 业务id,可以按需配置

* @param size 获取的id个数,与步长类似

*/

public static List getNoByGroup(RedisTemplate redisTemplate, String busId, int size) {

//保存redis中的key,注意不要重复

String redisKey = "uniqueNo_group";

//设置步长为size,相当于一次性申请size个id

Long increment = redisTemplate.opsForValue().increment(redisKey, size);

if (increment == null) {

throw new RuntimeException("redis命令执行失败");

}

long begin = increment - Long.parseLong(size + "");

List rs = new ArrayList<>();

for (long i = begin + 1; i <= increment; i++) {

rs.add(busId + i);

}

return rs;

}

总结

无论我们需要什么格式的ID,其实只要我们把握住其中的核心:incrBy命令,根据其原子性的特性,就可以生成我们需要的全局ID。

但是需要注意的是,虽然incrBy命令是原子性的,但是通过组合键进行组合时,其实是破坏了这种原子性。如果有特殊的ID格式要求,务必要进行充分的测试。

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!