国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Redis 緩存穿透、緩存雪崩、緩存擊穿

這篇具有很好參考價(jià)值的文章主要介紹了Redis 緩存穿透、緩存雪崩、緩存擊穿。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

緩存穿透

緩存穿透是指客戶端請(qǐng)求的數(shù)據(jù)在緩存中和數(shù)據(jù)庫(kù)中都不存在,這樣緩存永遠(yuǎn)不會(huì)生效,這些請(qǐng)求都會(huì)打到數(shù)據(jù)庫(kù)。

常見的解決方案有兩種:

????????緩存空對(duì)象

???????? ????????優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,維護(hù)方便

????????????????缺點(diǎn): 額外的內(nèi)存消耗 可能造成短期的不一致(惡意攻擊的對(duì)象id對(duì)應(yīng)的redis空值緩存失效前成為了新插入的id,造成真實(shí)客戶只能得到空緩存)

????????布隆過(guò)濾(類似于位示圖0、1代表是否存在)

????????????????優(yōu)點(diǎn):內(nèi)存占用較少,沒(méi)有多余key

????????????????缺點(diǎn): 實(shí)現(xiàn)復(fù)雜 存在誤判可能(對(duì)于過(guò)濾結(jié)果:假的一定為假,真的有小概率為假)

Redis 緩存穿透、緩存雪崩、緩存擊穿Redis 緩存穿透、緩存雪崩、緩存擊穿

?Redis 緩存穿透、緩存雪崩、緩存擊穿

?緩存穿透的解決方案有哪些?

緩存null值

布隆過(guò)濾

增強(qiáng)id的復(fù)雜度,避免被猜測(cè)id規(guī)律

做好數(shù)據(jù)的基礎(chǔ)格式校驗(yàn)

加強(qiáng)用戶權(quán)限校驗(yàn)

做好熱點(diǎn)參數(shù)的限流

代碼解釋,這是一個(gè)通用的工具類方法:

public <R,ID> R queryWithPassThrough(
            String keyPrefix, ID id, Class<R> type, Function<ID,R> dbFallback,Long time,TimeUnit unit){
        String key=keyPrefix+id;
        String json = stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(json)){
            return JSONUtil.toBean(json,type);
        }
        if (json!=null){
            return null;
        }
        R apply = dbFallback.apply(id);
        if (apply==null){    //生成空值緩存,避免緩存穿透
            stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL, TimeUnit.MINUTES);  //對(duì)象轉(zhuǎn)Json
            return null;
        }
        this.set(key,JSONUtil.toJsonStr(apply),time, unit);
        return apply;
    }

緩存雪崩

緩存雪崩是指在同一時(shí)段大量的緩存key同時(shí)失效或者Redis服務(wù)宕機(jī),導(dǎo)致大量請(qǐng)求到達(dá)數(shù)據(jù)庫(kù),帶來(lái)巨大壓力。

解決方案:

給不同的Key的TTL添加隨機(jī)值

利用Redis集群提高服務(wù)的可用性

給緩存業(yè)務(wù)添加降級(jí)限流策略

給業(yè)務(wù)添加多級(jí)緩存

緩存擊穿

緩存擊穿問(wèn)題也叫熱點(diǎn)Key問(wèn)題,就是一個(gè)被高并發(fā)訪問(wèn)并且緩存重建業(yè)務(wù)較復(fù)雜的key突然失效了,無(wú)數(shù)的請(qǐng)求訪問(wèn)會(huì)在瞬間給數(shù)據(jù)庫(kù)帶來(lái)巨大的沖擊。

常見的解決方案有兩種:

互斥鎖、邏輯過(guò)期

Redis 緩存穿透、緩存雪崩、緩存擊穿

Redis 緩存穿透、緩存雪崩、緩存擊穿

?Redis 緩存穿透、緩存雪崩、緩存擊穿文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-431363.html

基于代碼實(shí)現(xiàn)互斥鎖

public <R,ID> R queryWithMutex(String keyPrefix,ID id,Class<R> type,Function<ID,R> dbrFallback,Long time,TimeUnit unit){
        String key= keyPrefix+id;
        String shopJson= stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(shopJson)){  //命中Redis緩存
            return JSONUtil.toBean(shopJson, type);
        }
        if(shopJson!=null){     //命中空值緩存,代表惡意攻擊
            return null;
        }

        if (!tryLock(LOCK_SHOP_KEY+id)) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return queryWithMutex(keyPrefix,id,type,dbrFallback,time,unit);
        }
        String shopJson2= stringRedisTemplate.opsForValue().get(key);
        //doubleCheck
        if (StrUtil.isNotBlank(shopJson2)){  //命中Redis緩存
            unlock(LOCK_SHOP_KEY+id);
            return JSONUtil.toBean(shopJson2, type);
        }
        if(shopJson2!=null){     //命中空值緩存,代表惡意攻擊
            unlock(LOCK_SHOP_KEY+id);
            return null;
        }
        R apply = dbrFallback.apply(id);
        if (apply==null){    //生成空值緩存,避免緩存穿透
            stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL, TimeUnit.MINUTES);  //對(duì)象轉(zhuǎn)Json
            return null;
        }
        this.setWithLogicalExpire(key,JSONUtil.toJsonStr(apply),time,unit);
        unlock(LOCK_SHOP_KEY+id);
        return apply;
    }

基于代碼實(shí)現(xiàn)邏輯過(guò)期?

    public <R,ID> R queryWithLogicalExpire(
            String keyPrefix, ID id, Class<R> type, Function<ID,R> dbFallback,Long time,TimeUnit unit){
        String key= CACHE_SHOP_KEY+id;
        String Json= stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isBlank(Json)){  //未命中Redis緩存
            return null;
        }
        RedisData redisData = JSONUtil.toBean(Json, RedisData.class);
        R r = JSONUtil.toBean((JSONObject) redisData.getData(), type);
        if (redisData.getExpireTime().isAfter(LocalDateTime.now())){
            return r;
        }
        if (tryLock(key)){
            String json=stringRedisTemplate.opsForValue().get(key);
            if (StrUtil.isNotBlank(json)){  //命中Redis緩存 二次命中緩存,兜底
                RedisData redisData1 = JSONUtil.toBean(json, RedisData.class);
                if (redisData1.getExpireTime().isAfter(LocalDateTime.now())){
                    unlock(key);
                    return JSONUtil.toBean((JSONObject) redisData1.getData(), type);
                }
            }
            CACHE_REBUILD_EXECUTOR.submit(()->{
                R apply = dbFallback.apply(id);
                this.setWithLogicalExpire(key,apply,time,unit);
                unlock(key);
            });
        }
        return r;
    }

附工具類方法

    public void set(String key, Object value, Long time, TimeUnit util){
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(value),time,util);
    }
    public void setWithLogicalExpire(String key, Object value, Long time, TimeUnit util){
        RedisData redisData=new RedisData();
        redisData.setData(value);
        redisData.setExpireTime(LocalDateTime.now().plusSeconds(util.toSeconds(time)));
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(redisData));
    }
    //線程池
    public static final ExecutorService CACHE_REBUILD_EXECUTOR =             
    Executors.newFixedThreadPool(10);
    /**
     * 獲取互斥鎖
     * @param key
     * @return
     */
    public Boolean tryLock(String key){
        Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", LOCK_SHOP_TTL, TimeUnit.SECONDS);
        return BooleanUtil.isTrue(aBoolean);
    }

    /**
     * 釋放互斥鎖
     * @param key
     * @return
     */
    public void unlock(String key){
        stringRedisTemplate.delete(key);
    }

到了這里,關(guān)于Redis 緩存穿透、緩存雪崩、緩存擊穿的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Redis之緩存穿透+緩存雪崩+緩存擊穿

    Redis之緩存穿透+緩存雪崩+緩存擊穿

    在生產(chǎn)環(huán)境中,會(huì)因?yàn)楹芏嗟脑蛟斐稍L問(wèn)請(qǐng)求繞過(guò)了緩存,都需要訪問(wèn)數(shù)據(jù)庫(kù)持久層,雖然對(duì)Redsi緩存服務(wù)器不會(huì)造成影響,但是數(shù)據(jù)庫(kù)的負(fù)載就會(huì)增大,使緩存的作用降低 ??緩存穿透是指查詢一個(gè)根本不存在的數(shù)據(jù),緩存層和持久層都不會(huì)命中。在日常工作中出于容錯(cuò)

    2023年04月09日
    瀏覽(24)
  • Redis的緩存穿透,緩存擊穿,緩存雪崩

    Redis的緩存穿透,緩存擊穿,緩存雪崩

    什么是緩存穿透? 緩存穿透說(shuō)簡(jiǎn)單點(diǎn)就是大量請(qǐng)求的 key 是不合理的, 根本不存在于緩存中,也不存在于數(shù)據(jù)庫(kù)中 。這就導(dǎo)致這些請(qǐng)求直接到了數(shù)據(jù)庫(kù)上,根本沒(méi)有經(jīng)過(guò)緩存這一層,對(duì)數(shù)據(jù)庫(kù)造成了巨大的壓力,可能直接就被這么多請(qǐng)求弄宕機(jī)了。 eg:某個(gè)黑客故意制造一

    2024年02月10日
    瀏覽(20)
  • 68、Redis:緩存雪崩、緩存穿透、緩存擊穿

    緩存雪崩是指緩存同一時(shí)間大面積的失效,所以,后面的請(qǐng)求都會(huì)落到數(shù)據(jù)庫(kù)上,造成數(shù)據(jù)庫(kù)短時(shí)間內(nèi)承受大量請(qǐng)求而崩掉。 緩存數(shù)據(jù)的過(guò)期時(shí)間設(shè)置隨機(jī),防止同一時(shí)間大量數(shù)據(jù)過(guò)期現(xiàn)象發(fā)生 給每一個(gè)緩存數(shù)據(jù)增加相應(yīng)的緩存標(biāo)記,記錄緩存是否失效,如果緩存標(biāo)記失效

    2024年02月16日
    瀏覽(22)
  • Redis 緩存預(yù)熱+緩存雪崩+緩存擊穿+緩存穿透

    Redis 緩存預(yù)熱+緩存雪崩+緩存擊穿+緩存穿透

    面試題: 緩存預(yù)熱、雪萌、穿透、擊穿分別是什么?你遇到過(guò)那幾個(gè)情況? 緩存預(yù)熱你是怎么做的? 如何造免或者減少緩存雪崩? 穿透和擊穿有什么區(qū)別?他兩是一個(gè)意思還是載然不同? 穿適和擊穿你有什么解決方案?如何避免? 假如出現(xiàn)了緩存不一致,你有哪些修補(bǔ)方

    2024年02月10日
    瀏覽(20)
  • Redis(緩存預(yù)熱,緩存雪崩,緩存擊穿,緩存穿透)

    Redis(緩存預(yù)熱,緩存雪崩,緩存擊穿,緩存穿透)

    目錄 一、緩存預(yù)熱 二、緩存雪崩 三、緩存擊穿 四、緩存穿透 ? 開過(guò)車的都知道,冬天的時(shí)候啟動(dòng)我們的小汽車之后不要直接駕駛,先讓車子發(fā)動(dòng)機(jī)預(yù)熱一段時(shí)間再啟動(dòng)。緩存預(yù)熱是一樣的道理。 緩存預(yù)熱就是系統(tǒng)啟動(dòng)前,提前將相關(guān)的緩存數(shù)據(jù)直接加載到緩存系統(tǒng)。避免

    2024年02月10日
    瀏覽(36)
  • Redis緩存預(yù)熱-緩存穿透-緩存雪崩-緩存擊穿

    Redis緩存預(yù)熱-緩存穿透-緩存雪崩-緩存擊穿

    什么叫緩存穿透? 模擬一個(gè)場(chǎng)景: 前端用戶發(fā)送請(qǐng)求獲取數(shù)據(jù),后端首先會(huì)在緩存Redis中查詢,如果能查到數(shù)據(jù),則直接返回.如果緩存中查不到數(shù)據(jù),則要去數(shù)據(jù)庫(kù)查詢,如果數(shù)據(jù)庫(kù)有,將數(shù)據(jù)保存到Redis緩存中并且返回用戶數(shù)據(jù).如果數(shù)據(jù)庫(kù)沒(méi)有則返回null; 這個(gè)緩存穿透的問(wèn)題就是這個(gè)

    2024年03月09日
    瀏覽(30)
  • redis緩存雪崩、穿透和擊穿

    redis緩存雪崩、穿透和擊穿

    緩存雪崩 ? 對(duì)于系統(tǒng) A,假設(shè)每天高峰期每秒 5000 個(gè)請(qǐng)求,本來(lái)緩存在高峰期可以扛住每秒 4000 個(gè)請(qǐng)求,但是緩存機(jī)器意外發(fā)生了全盤宕機(jī)或者大量緩存集中在某一個(gè)時(shí)間段失效。緩存掛了,此時(shí) 1 秒 5000 個(gè)請(qǐng)求全部落數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)必然扛不住,它會(huì)報(bào)一下警,然后就掛了

    2024年01月22日
    瀏覽(19)
  • Redis 緩存雪崩、穿透、擊穿、預(yù)熱

    Redis 緩存雪崩、穿透、擊穿、預(yù)熱

    ????????在實(shí)際工程中,Redis 緩存問(wèn)題常伴隨高并發(fā)場(chǎng)景出現(xiàn)。例如, 電商大促、活動(dòng)報(bào)名、突發(fā)新聞 時(shí),由于緩存失效導(dǎo)致大量請(qǐng)求訪問(wèn)數(shù)據(jù)庫(kù),導(dǎo)致 雪崩 、 擊穿 、 穿透 等問(wèn)題。因此,新系統(tǒng)上線前需 預(yù)熱 緩存,以應(yīng)對(duì)高并發(fā),減輕數(shù)據(jù)庫(kù)壓力。本章主要圍繞這

    2024年04月12日
    瀏覽(24)
  • Redis 緩存穿透擊穿和雪崩

    Redis 緩存穿透擊穿和雪崩

    ???????? Redis 緩存的使用,極大的提升了應(yīng)用程序的性能和效率,特別是數(shù)據(jù)查詢方面。但同時(shí),它也帶來(lái)了一些問(wèn)題。其中,最要害的問(wèn)題,就是數(shù)據(jù)的一致性問(wèn)題,從嚴(yán)格意義上講,這個(gè)問(wèn)題無(wú)解。如果對(duì)數(shù)據(jù)的一致性要求很高,那么就不能使用緩存。 2.1 概念 ???

    2024年02月10日
    瀏覽(34)
  • Redis的緩存穿透、緩存擊穿和緩存雪崩

    Redis的緩存穿透、緩存擊穿和緩存雪崩

    目錄 一、解釋說(shuō)明 二、緩存穿透 ?1.?什么是緩存穿透? ?2. 常見的兩種解決方案 ?(1)緩存空對(duì)象 ?(2)布隆過(guò)濾 3.?編碼解決商品查詢的緩存穿透問(wèn)題 三、緩存擊穿 ?1.? 什么是緩存擊穿? ?2、緩存擊穿解決方案(2種) (1)互斥鎖 (2)邏輯過(guò)期 ?3.? 互斥鎖與邏輯過(guò)

    2024年02月14日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包