欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何通過(guò)redis減庫(kù)存的秒殺場(chǎng)景實(shí)現(xiàn)

 更新時(shí)間:2022年06月01日 10:42:34   作者:ZNineSun  
本文通過(guò)解決秒殺系統(tǒng)中的一個(gè)場(chǎng)景即數(shù)據(jù)預(yù)加載,即把庫(kù)存數(shù)據(jù)事先加載到緩存,然后通過(guò)緩存來(lái)更新庫(kù)存,簡(jiǎn)單介紹了如何通過(guò)redis減庫(kù)存的秒殺場(chǎng)景實(shí)現(xiàn),感興趣的可以了解一下

Redis扣庫(kù)存,主要目的是減少對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),之前的減庫(kù)存,直接訪問(wèn)數(shù)據(jù)庫(kù),讀取庫(kù)存,當(dāng)高并發(fā)請(qǐng)求到來(lái)的時(shí)候,大量的讀取數(shù)據(jù)有可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)的崩潰。

大家可以先讀一下《秒殺系統(tǒng)設(shè)計(jì)》對(duì)整體的秒殺流程有個(gè)了解之后,在來(lái)讀一下這篇文章。

本文只是解決秒殺系統(tǒng)中的一個(gè)場(chǎng)景即數(shù)據(jù)預(yù)加載,即把庫(kù)存數(shù)據(jù)事先加載到緩存,然后通過(guò)緩存來(lái)更新庫(kù)存。

使用思路:

  • 系統(tǒng)初始化的時(shí)候,將商品庫(kù)存加載到Redis 緩存中保存。
  • 收到請(qǐng)求的時(shí)候,先在Redis中拿到該商品的庫(kù)存值,進(jìn)行庫(kù)存預(yù)減,如果減完之后庫(kù)存不足,直接返回邏輯Exception就不需要訪問(wèn)數(shù)據(jù)庫(kù)再去減庫(kù)存了,如果庫(kù)存值正確,進(jìn)行下一步。
  • 將請(qǐng)求入隊(duì),立即給前端返回一個(gè)值,表示正在排隊(duì)中,然后進(jìn)行秒殺邏輯,后端隊(duì)列進(jìn)行秒殺邏輯,前端輪詢后端發(fā)來(lái)的請(qǐng)求,如果秒殺成功,返回秒殺,成功,不成功就返回失敗。

第一步:系統(tǒng)初始化后就將所有商品庫(kù)存放入緩存

/**
 * 秒殺接口優(yōu)化之---   第一步:  系統(tǒng)初始化后就將所有商品庫(kù)存放入 緩存
 */
@Override
public void afterPropertiesSet() throws Exception {
    List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {
        return;
    }
    for (GoodsVo goodsVo : goods) {
        redisService.set(GoodsKey.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);//先初始化 每個(gè)商品都是false 就是還有
    }
}

第二步: 預(yù)減庫(kù)存從緩存中減庫(kù)存

/**秒殺接口優(yōu)化之 ----第二步: 預(yù)減庫(kù)存 從緩存中減庫(kù)存
 * 利用 redis 中的方法,減去庫(kù)存,返回值為 減去1 之后的值
 * */
long stock = redisService.decr(GoodsKey.getGoodsStock, "" + goodsId);
/*這里判斷不能小于等于,因?yàn)闇p去之后等于 說(shuō)明還有是正常范圍*/
if (stock < 0) {
    isOverMap.put(goodsId, true);//沒(méi)有庫(kù)存就設(shè)置 對(duì)應(yīng)id 商品的map 為true
    return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
}

整體的邏輯如下:

1.先將所有數(shù)據(jù)讀出來(lái),初始化到緩存中,并以 stock + goodid 的形成存入Redis。

2.在秒殺的時(shí)候,先進(jìn)行預(yù)減庫(kù)存檢測(cè),從redis中,利用decr 減去對(duì)應(yīng)商品的庫(kù)存,如果庫(kù)存小于0,說(shuō)明此時(shí) 庫(kù)存不足,則不需要訪問(wèn)數(shù)據(jù)庫(kù)。直接拋出異常即可。
我們上面還使用到了isOverMap,這個(gè)是內(nèi)存標(biāo)記。

內(nèi)存標(biāo)記

由于接口優(yōu)化很多基于Redis的緩存操作,當(dāng)并發(fā)很高的時(shí)候,也會(huì)給Redis服務(wù)器帶來(lái)很大的負(fù)擔(dān),如果可以減少對(duì)Redis服務(wù)器的訪問(wèn),也可以達(dá)到的優(yōu)化的效果。

于是,可以加一個(gè)內(nèi)存map,標(biāo)記對(duì)應(yīng)商品的庫(kù)存量是否還有,在訪問(wèn)Redis之前,在map中拿到對(duì)應(yīng)商品的庫(kù)存量標(biāo)記,就可以不需要訪問(wèn)Redis 就可以判斷沒(méi)有庫(kù)存了。

1.生成一個(gè)map,并在初始化的時(shí)候,將所有商品的id為鍵,標(biāo)記false 存入map中。

private Map<Long, Boolean> isOverMap = new HashMap<Long, Boolean>();
/**
 * 秒殺接口優(yōu)化之---   第一步:  系統(tǒng)初始化后就將所有商品庫(kù)存放入 緩存
 */
@Override
public void afterPropertiesSet() throws Exception {
    List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {
        return;
    }
    for (GoodsVo goodsVo : goods) {
        redisService.set(GoodsKey.getGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);//先初始化 每個(gè)商品都是false 就是還有
    }
}
/**再優(yōu)化: 優(yōu)化 庫(kù)存之后的請(qǐng)求不訪問(wèn)redis 通過(guò)判斷 對(duì)應(yīng) map 的值
? * */
boolean isOver = isOverMap.get(goodsId);
if (isOver) {
? ? ?return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
}

if (stock < 0) {
? ? ?isOverMap.put(goodsId, true);//沒(méi)有庫(kù)存就設(shè)置 對(duì)應(yīng)id 商品的map 為true
}

2.在預(yù)減庫(kù)存之前,從map中取標(biāo)記,若標(biāo)記為false,說(shuō)明庫(kù)存

3.預(yù)減庫(kù)存,當(dāng)遇到庫(kù)存不足的時(shí)候,將該商品的標(biāo)記置為true,表示該商品的庫(kù)存不足。這樣,下面的所有請(qǐng)求,將被攔截,無(wú)需訪問(wèn)redis進(jìn)行預(yù)減庫(kù)存。

所以利用緩存的整體思路如下:

將商品的庫(kù)存數(shù)據(jù)加載至內(nèi)存,同時(shí)初始化內(nèi)存標(biāo)記,即把每個(gè)產(chǎn)品的id存放至map,都是初始化為false,在每次需要執(zhí)行秒殺邏輯之前,在在內(nèi)存標(biāo)記中取值,如果仍有庫(kù)存即map里返回的為false,則 執(zhí)行秒殺邏輯,否則直接拋出異常。

同時(shí)扣減庫(kù)存時(shí),需要判斷緩存中的庫(kù)存數(shù)量是否仍然大于0,如果小于等于0,修改內(nèi)存標(biāo)記。

到此這篇關(guān)于如何通過(guò)redis減庫(kù)存的秒殺場(chǎng)景實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)redis減庫(kù)存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以

相關(guān)文章

  • 解析redis hash應(yīng)用場(chǎng)景和常用命令

    解析redis hash應(yīng)用場(chǎng)景和常用命令

    這篇文章主要介紹了redis hash應(yīng)用場(chǎng)景和常用命令,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Redis整合Spring結(jié)合使用緩存實(shí)例

    Redis整合Spring結(jié)合使用緩存實(shí)例

    這篇文章主要介紹了Redis整合Spring結(jié)合使用緩存實(shí)例,介紹了如何在Spring中配置redis,并通過(guò)Spring中AOP的思想,將緩存的方法切入到有需要進(jìn)入緩存的類或方法前面。需要的朋友可以參考下
    2015-12-12
  • redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn)

    redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn)

    使用Redis計(jì)數(shù)器可以輕松地解決數(shù)量控制的問(wèn)題,同時(shí)還能有效地提高應(yīng)用的性能,本文主要介紹了redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Redis不僅僅是緩存,還是……

    Redis不僅僅是緩存,還是……

    Redis是一個(gè)開(kāi)源的(BSD協(xié)議),內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ),它可以用作數(shù)據(jù)庫(kù),緩存,消息代理。這篇文章主要介紹了Redis不僅僅是緩存,還是……,需要的朋友可以參考下
    2020-12-12
  • Redis動(dòng)態(tài)字符串SDS的實(shí)現(xiàn)

    Redis動(dòng)態(tài)字符串SDS的實(shí)現(xiàn)

    SDS在Redis中是實(shí)現(xiàn)字符串對(duì)象的工具,本文主要介紹了Redis動(dòng)態(tài)字符串SDS的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • 手把手教你使用redis實(shí)現(xiàn)排行榜功能

    手把手教你使用redis實(shí)現(xiàn)排行榜功能

    使用Redis中有序集合的特性來(lái)實(shí)現(xiàn)排行榜是又好又快的選擇,一般排行榜都是有實(shí)效性的,比如“用戶積分榜”,下面這篇文章主要給大家介紹了關(guān)于使用redis實(shí)現(xiàn)排行榜功能的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • redis添加key幾種方式

    redis添加key幾種方式

    本文主要介紹了redis添加key幾種方式,主要介紹了3種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • 一文帶你了解Redis中RDB與AOF的區(qū)別

    一文帶你了解Redis中RDB與AOF的區(qū)別

    Redis 在持久化時(shí),給我們提供了兩種方式,這兩種方式就是 RDB 與 AOF,那這兩種方式有什么區(qū)別呢,本文就帶大家詳細(xì)的了解一下二者的區(qū)別,需要的朋友可以參考下
    2023-06-06
  • Redis Sentinel的基本搭建

    Redis Sentinel的基本搭建

    這篇文章主要介紹了Redis Sentinel的使用,幫助大家更好的理解和學(xué)習(xí)使用Redis數(shù)據(jù)庫(kù),感興趣的朋友可以了解下
    2021-03-03
  • NestJS+Redis實(shí)現(xiàn)手寫(xiě)一個(gè)限流器

    NestJS+Redis實(shí)現(xiàn)手寫(xiě)一個(gè)限流器

    限流是大型系統(tǒng)必備的保護(hù)措施,本文將結(jié)合redis , lua 腳本 以及 Nestjs Guard 來(lái)實(shí)現(xiàn) 限流的效果,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11

最新評(píng)論