最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis緩存及熱點key問題解決方案

 更新時間:2020年04月13日 10:57:29   作者:天際星痕  
這篇文章主要介紹了Redis緩存及熱點key問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

今天又學(xué)到了很多,感覺雪崩和穿透很有意思理解起來也比較清晰,然后我搜索了一些資料,給自己做一個普及

我們通常使用 緩存 + 過期時間的策略來幫助我們加速接口的訪問速度,減少了后端負(fù)載,同時保證功能的更新

緩存穿透

緩存系統(tǒng),按照KEY去查詢VALUE,當(dāng)KEY對應(yīng)的VALUE一定不存在的時候并對KEY并發(fā)請求量很大的時候,就會對后端造成很大的壓力。

(查詢一個必然不存在的數(shù)據(jù)。比如文章表,查詢一個不存在的id,每次都會訪問DB,如果有人惡意破壞,很可能直接對DB造成影響。)

由于緩存不命中,每次都要查詢持久層。從而失去緩存的意義。

解決方法:

1、緩存層緩存空值。

–緩存太多空值,占用更多空間。(優(yōu)化:給個空值過期時間)
–存儲層更新代碼了,緩存層還是空值。(優(yōu)化:后臺設(shè)置時主動刪除空值,并緩存把值進(jìn)去)

2、將數(shù)據(jù)庫中所有的查詢條件,放到布隆過濾器中。當(dāng)一個查詢請求來臨的時候,先經(jīng)過布隆過濾器進(jìn)行檢查,如果請求存在這個條件中,那么繼續(xù)執(zhí)行,如果不在,直接丟棄。

備注:

比如數(shù)據(jù)庫中有10000個條件,那么布隆過濾器的容量size設(shè)置的要稍微比10000大一些,比如12000.

對于誤判率的設(shè)置,根據(jù)實際項目,以及硬件設(shè)施來具體決定。但是一定不能設(shè)置為0,并且誤判率設(shè)置的越小,哈希函數(shù)跟數(shù)組長度都會更多跟更長,那么對硬件,內(nèi)存中間的要求就會相應(yīng)的高。

private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.0001);

有了size跟誤判率,那么布隆過濾器就會產(chǎn)生相應(yīng)的哈希函數(shù)跟數(shù)組。

綜上:我們可以利用布隆過濾器,將redis緩存擊穿控制在一個可容忍的范圍內(nèi)。

緩存雪崩(緩存失效)

如果緩存集中在一段時間內(nèi)失效,發(fā)生大量的緩存穿透,所有的查詢都落在數(shù)據(jù)庫上,造成了緩存雪崩。

緩存層宕掉后,流量會像奔逃的野牛一樣,打向后端存儲

解決方法:

  • 在緩存失效后,通過加鎖或者隊列來控制讀數(shù)據(jù)庫寫緩存的線程數(shù)量。比如對某個key只允許一個線程查詢數(shù)據(jù)和寫緩存,其他線程等待。
  • 可以通過緩存reload機(jī)制,預(yù)先去更新緩存,再即將發(fā)生大并發(fā)訪問前手動觸發(fā)加載緩存
  • 不同的key,設(shè)置不同的過期時間,讓緩存失效的時間點盡量均勻
  • 做二級緩存,或者雙緩存策略。A1為原始緩存,A2為拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設(shè)置為短期,A2設(shè)置為長期。

熱點key

(1) 這個key是一個熱點key(例如一個重要的新聞,一個熱門的八卦新聞等等),所以這種key訪問量可能非常大。

(2) 緩存的構(gòu)建是需要一定時間的。(可能是一個復(fù)雜計算,例如復(fù)雜的sql、多次IO、多個依賴(各種接口)等等)

于是就會出現(xiàn)一個致命問題:在緩存失效的瞬間,有大量線程來構(gòu)建緩存(見下圖),造成后端負(fù)載加大,甚至可能會讓系統(tǒng)崩潰 。

解決方法:

1. 使用互斥鎖(mutex key):這種解決方案思路比較簡單,就是只讓一個線程構(gòu)建緩存,其他線程等待構(gòu)建緩存的線程執(zhí)行完,重新從緩存獲取數(shù)據(jù)就可以了

2. "提前"使用互斥鎖(mutex key):在value內(nèi)部設(shè)置1個超時值(timeout1), timeout1比實際的memcache timeout(timeout2)小。當(dāng)從cache讀取到timeout1發(fā)現(xiàn)它已經(jīng)過期時候,馬上延長timeout1并重新設(shè)置到cache。然后再從數(shù)據(jù)庫加載數(shù)據(jù)并設(shè)置到cache中。

3. "永遠(yuǎn)不過期":

這里的“永遠(yuǎn)不過期”包含兩層意思:

(1) 從redis上看,確實沒有設(shè)置過期時間,這就保證了,不會出現(xiàn)熱點key過期問題,也就是“物理”不過期。

(2) 從功能上看,如果不過期,那不就成靜態(tài)的了嗎?所以我們把過期時間存在key對應(yīng)的value里,如果發(fā)現(xiàn)要過期了,通過一個后臺的異步線程進(jìn)行緩存的構(gòu)建,也就是“邏輯”過期

4. 資源保護(hù):可以做資源的隔離保護(hù)主線程池,如果把這個應(yīng)用到緩存的構(gòu)建也未嘗不可。

四種方案對比:

作為一個并發(fā)量較大的互聯(lián)網(wǎng)應(yīng)用,我們的目標(biāo)有3個:

1. 加快用戶訪問速度,提高用戶體驗。

2. 降低后端負(fù)載,保證系統(tǒng)平穩(wěn)。

3. 保證數(shù)據(jù)“盡可能”及時更新(要不要完全一致,取決于業(yè)務(wù),而不是技術(shù)。)

所以第二節(jié)中提到的四種方法,可以做如下比較,還是那就話:沒有最好,只有最合適。

解決方案 優(yōu)點 缺點
簡單分布式鎖(Tim yang)

 1. 思路簡單

2. 保證一致性

1. 代碼復(fù)雜度增大

2. 存在死鎖的風(fēng)險

3. 存在線程池阻塞的風(fēng)險

加另外一個過期時間(Tim yang)  1. 保證一致性 同上 
不過期(本文)

1. 異步構(gòu)建緩存,不會阻塞線程池

1. 不保證一致性。

2. 代碼復(fù)雜度增大(每個value都要維護(hù)一個timekey)。

3. 占用一定的內(nèi)存空間(每個value都要維護(hù)一個timekey)。

資源隔離組件hystrix(本文)

1. hystrix技術(shù)成熟,有效保證后端。

2. hystrix監(jiān)控強(qiáng)大。

1. 部分訪問存在降級策略。 

總結(jié)

1. 熱點key + 過期時間 + 復(fù)雜的構(gòu)建緩存過程 => mutex key問題

2. 構(gòu)建緩存一個線程做就可以了。

3. 四種解決方案:沒有最佳只有最合適。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在IDEA中安裝MyBatis Log Plugin插件,執(zhí)行mybatis的sql語句(推薦)

    在IDEA中安裝MyBatis Log Plugin插件,執(zhí)行mybatis的sql語句(推薦)

    這篇文章主要介紹了在IDEA中安裝MyBatis Log Plugin插件,執(zhí)行mybatis的sql語句,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java處理日期時間的方法匯總

    Java處理日期時間的方法匯總

    這篇文章主要給大家介紹了利用Java中的Calendar 類處理日期時間的方法匯總,其中包括取日期的每部分、取當(dāng)月的第一天或最后一天、求兩個日期之間相隔的天數(shù)以及一年前的日期等等的示例代碼,有需要的朋友們可以直接參考借鑒,下面來一起看看吧。
    2016-12-12
  • 基于SpringBoot使用MyBatis插件的問題

    基于SpringBoot使用MyBatis插件的問題

    MyBatis-Plus并不能為我們解決所有問題,例如一些復(fù)雜的SQL,多表聯(lián)查,我們就需要自己去編寫代碼和SQL語句,我們該如何快速的解決這個問題呢,這個時候可以使用MyBatisX插件,今天小編給大家?guī)砹薙pringBoot使用MyBatis插件問題,感興趣的朋友一起看看吧
    2022-03-03
  • SpringCloud如何實現(xiàn)Zuul集群(負(fù)載均衡)

    SpringCloud如何實現(xiàn)Zuul集群(負(fù)載均衡)

    這篇文章主要介紹了SpringCloud如何實現(xiàn)Zuul集群(負(fù)載均衡)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 最新評論

    瑞金市| 舞钢市| 宜兴市| 桐乡市| 满城县| 红原县| 辽源市| 三原县| 宁乡县| 峡江县| 德令哈市| 宁蒗| 长岭县| 耒阳市| 西盟| 南康市| 内江市| 改则县| 舞阳县| 陆良县| 宣化县| 东台市| 甘洛县| 利辛县| 西盟| 哈尔滨市| 牟定县| 阿拉善盟| 兰坪| 文登市| 阳新县| 彰化市| 韩城市| 瑞丽市| 扶绥县| 花垣县| 苍山县| 黑龙江省| 盐源县| 荆门市| 博白县|