简单实用!利用Redis轻松实现高并发全局ID生成器
Redis作为高性能的KV数据库,并且操作还是原子性的,所以用来做支持高并发的发号器十分合适。
本文给大家介绍3种常见的全局ID生成方式。
1、全局递增ID
目标:一直递增的全局ID。
/**
* 一直递增的全局id
*
* @param redisTemplate redis客户端对象
* @param busId 业务id,可以按需配置
* @param step 步长,即每次递增的间隔
*/
public static String getNo(RedisTemplate<String, Object> 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<String, Object> 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<String> getNoByGroup(RedisTemplate<String, Object> 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<String> rs = new ArrayList<>();
for (long i = begin + 1; i <= increment; i++) {
rs.add(busId + i);
}
return rs;
}
总结
无论我们需要什么格式的ID,其实只要我们把握住其中的核心:incrBy命令,根据其原子性的特性,就可以生成我们需要的全局ID。
但是需要注意的是,虽然incrBy命令是原子性的,但是通过组合键进行组合时,其实是破坏了这种原子性。如果有特殊的ID格式要求,务必要进行充分的测试。
>更多相关文章
- 06-16卡巴斯基郑启良:支持信创发展是卡巴斯基的重要使命
- 06-16访问管理是确保现代工作场所安全的的五个关键原因
- 06-16零信任安全的演变:彻底改变网络安全策略
- 06-16GitHub上值得关注的20个网络安全项目
- 06-16英国曼彻斯特大学遭遇网络攻击,机密数据或遭窃!
- 06-16调查表明广告软件推送恶意软件感染了六万多个安卓应用程序
- 06-16微软向美国政府提供GPT的大模型,安全性如何保证?
- 06-16如何保护OT环境免受安全威胁?
首页推荐
佛山市东联科技有限公司一直秉承“一切以用户价值为依归
- 01-11全球最受赞誉公司揭晓:苹果连续九年第一
- 12-09罗伯特·莫里斯:让黑客真正变黑
- 12-09谁闯入了中国网络?揭秘美国绝密黑客小组TA
- 12-09警示:iOS6 惊现“闪退”BUG
- 12-05亚马逊推出新一代基础模型 任意模态生成大模
- 12-05OpenAI拓展欧洲业务 将在苏黎世设立办公室
- 12-05微软质疑美国联邦贸易委员会泄露信息 督促其
- 12-05联交所取消宝宝树上市地位 宝宝树:不会对公
- 12-04企业微信致歉:文档打开异常已完成修复
相关文章
24小时热门资讯
24小时回复排行
热门推荐
最新资讯
操作系统
黑客防御