redis+guava 實現多級緩存

JAVA 基礎體系


雖然面對的是高併發場景,單今天只關注緩存,不討論線程安全和鎖相關的問題。

前言

日常工作中,時常要面對抽獎活動,獎勵發放,商品秒殺等大流量高併發的場景。
高併發場景面對的第一個問題是DB的IO瓶頸。 這時比較通用緩存方式是加一層redis,用內存的性能來解決IO的瓶頸。
但是引入Redis就一勞永逸了嘛?不是的,相對應的高併發場景又會引發Redis熱KEY和大KEY的問題,造成帶寬拉胯。
這時可以在做一層本地緩存。那麼問題又來了,本地緩存沒有過期時間啊,因此就可以用GUAVA CACHE來解決,本質上他就是封裝了一個過期時間,至於過期策略,一般有三種,定時刪除,定期刪除,惰性刪除,本地緩存,guava採用惰性刪除的方式就很合理。感興趣的同學,可以看下教程和源碼http://ifeve.com/google-guava,這裏不具體展開了。
附一張關鍵源碼圖:
在這裏插入圖片描述

場景與使用:

場景:動態配置獲取, 交易鏈路,需要獲取商家報名了活動,報名與否,會走不同的優惠策略。

首先要注意,爲防止緩存擊穿,我們不能依賴用戶請求來獲取配置,及時加鎖也不行,在交易鏈路使用分佈式鎖阻斷了交易就很坑。 所以,我們後臺起個TASK將數據跑入redis,緩存時間設置了3天防止過期。

  private List<Long> getSignupSellerUids(Long sellerActivityId) {
        // 報名商家sellerUid 本地緩存
        List<Long> localSignedupUids =
            signupUidsLocalCache.getIfPresent(AllowanceConstant.ALLOWANCE_SIGNEDUP_SELLERS_CACHE_KEY);
        if (Validator.isNotNull(localSignedupUids)) {
            return localSignedupUids;
        }

        // 本地沒命中 Redis緩存
        String signedUpCacheKey = BeidianAllowanceCacheUtils.getSignedUpSellersCacheKey(sellerActivityId);
        String confJsonStr = beidianRedisCacheClient.get(signedUpCacheKey);
        List<Long> cacheSignedUids = Validator.isNotNullOrEmpty(JSON.parseArray(confJsonStr, Long.TYPE)) ?
            JSON.parseArray(confJsonStr, Long.TYPE) :
            Collections.emptyList();
        if (!cacheSignedUids.isEmpty()) {
            signupUidsLocalCache.put(AllowanceConstant.ALLOWANCE_SIGNEDUP_SELLERS_CACHE_KEY, cacheSignedUids);
            return cacheSignedUids;
        }

        // 這裏已經是異常狀態了。
        return Collections.emptyList();
    }

一些會隨業務變化的動態配置,都非常適合使用多級緩存,讓你的程序穩穩當當喲~

沒有試過的小夥伴,一定要去試一試O(∩_∩)O

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章