Redis系列05 - redis+guava實現多級緩存

JAVA 基礎體系


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

前言

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

場景與使用:

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

首先要注意,爲防止緩存擊穿,我們不能依賴用戶請求來獲取配置,即使加鎖也不行,優惠是要強校驗的,使用分佈式鎖就阻斷了交易。 所以,我後臺起個Task將數據跑入redis,緩存時間設置了3天防止過期,任務10分鐘1次。下面是使用的場景

  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();
    }

場景二:首頁商品的ES數據,整體數據很多,又有千人千面, 所以可以單獨用Guava做一層當商品維度(商品iid維度)的緩存。

        List<String> iidCacheKeyList = new ArrayList<>();
        for (Object iid : beidianESCacheKeyBO.getIidList()) {
            iidCacheKeyList.add(getSingleItemESCacheKey(beidianESCacheKeyBO.getBaseItemESCacheKey(), iid));
        }
        Map<String, SearchItemTO> singleItemCacheMap = beidianSingleItemESCache.getAllPresent(iidCacheKeyList);

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

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

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