日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
簡(jiǎn)單實(shí)用!利用Redis輕松實(shí)現(xiàn)高并發(fā)全局ID生成器

Redis作為高性能的KV數(shù)據(jù)庫(kù),并且操作還是原子性的,所以用來(lái)做支持高并發(fā)的發(fā)號(hào)器十分合適。

本文給大家介紹3種常見的全局ID生成方式。

1、全局遞增ID

目標(biāo):一直遞增的全局ID。

/**
* 一直遞增的全局id
*
* @param redisTemplate redis客戶端對(duì)象
* @param busId 業(yè)務(wù)id,可以按需配置
* @param step 步長(zhǎng),即每次遞增的間隔
*/
public static String getNo(RedisTemplate redisTemplate, String busId, int step) {
//保存redis中的key,注意不要重復(fù)
String redisKey = "uniqueNo_";
//利用increment即redis原生incrBy命令的原子性特性生成遞增的序列號(hào)
Long increment = redisTemplate.opsForValue().increment(redisKey, step);
if (increment == null) {
throw new RuntimeException("redis命令執(zhí)行失敗");
}
//業(yè)務(wù)id+遞增id,如果需要純數(shù)字,去掉業(yè)務(wù)id即可
return busId + increment;
}

2、以天為分割的全局ID

目標(biāo):生成格式為 yyyyMMdd + 遞增序列號(hào)的全局ID。

/**
* 以天為間隔的遞增序列號(hào)
* @param redisTemplate redis客戶端對(duì)象
* @param busId 業(yè)務(wù)id,可以按需配置
* @param step 步長(zhǎng),即每次遞增的間隔
*/
public static String getNo(RedisTemplate redisTemplate, String busId, int step) {
//當(dāng)天日期,比如20221226
String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
//保存redis中的key,注意不要重復(fù)
String redisKey = "uniqueNo_" + date;
//利用increment即redis原生incrBy命令的原子性特性生成遞增的序列號(hào)
Long increment = redisTemplate.opsForValue().increment(redisKey, step);
if (increment == null) {
throw new RuntimeException("redis命令執(zhí)行失敗");
}
if (step == increment.intValue()) {
//首次執(zhí)行時(shí),給redisKey設(shè)置ttl,第二天這個(gè)key就可以被redis自動(dòng)刪除
redisTemplate.expire(redisKey, 25, TimeUnit.HOURS);
}
//組合 20221226 + 業(yè)務(wù)id + 0001(可以根據(jù)需要自由調(diào)整序列號(hào)的長(zhǎng)度)
return date + busId + String.format("%04d", increment);
}

3、批量獲取ID

有時(shí)我們需要批量的獲取遞增ID,比如給一批訂單號(hào)設(shè)置ID。

/**
* 批量獲取id
*
* @param redisTemplate redis客戶端對(duì)象
* @param busId 業(yè)務(wù)id,可以按需配置
* @param size 獲取的id個(gè)數(shù),與步長(zhǎng)類似
*/
public static List getNoByGroup(RedisTemplate redisTemplate, String busId, int size) {
//保存redis中的key,注意不要重復(fù)
String redisKey = "uniqueNo_group";
//設(shè)置步長(zhǎng)為size,相當(dāng)于一次性申請(qǐng)size個(gè)id
Long increment = redisTemplate.opsForValue().increment(redisKey, size);
if (increment == null) {
throw new RuntimeException("redis命令執(zhí)行失敗");
}
long begin = increment - Long.parseLong(size + "");
List rs = new ArrayList<>();
for (long i = begin + 1; i <= increment; i++) {
rs.add(busId + i);
}
return rs;
}

總結(jié)

無(wú)論我們需要什么格式的ID,其實(shí)只要我們把握住其中的核心:incrBy命令,根據(jù)其原子性的特性,就可以生成我們需要的全局ID。

但是需要注意的是,雖然incrBy命令是原子性的,但是通過組合鍵進(jìn)行組合時(shí),其實(shí)是破壞了這種原子性。如果有特殊的ID格式要求,務(wù)必要進(jìn)行充分的測(cè)試。


分享文章:簡(jiǎn)單實(shí)用!利用Redis輕松實(shí)現(xiàn)高并發(fā)全局ID生成器
鏈接地址:http://www.5511xx.com/article/cdogggc.html