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

詳解Redis緩存穿透/擊穿/雪崩原理及其解決方案

 更新時間:2021年09月01日 17:13:14   作者:張鐵牛  
緩存可以比喻為防彈衣,但如果沒有使用好這個防彈衣效果就會適得其反,所以要更好的使用緩存才能發(fā)揮出它的作用。本文詳細講解了緩存穿透/擊穿/雪崩以及其解決方法,感興趣的小伙伴可以學習一下這篇文章

1. 簡介

如圖所示,一個正常的請求

1.客戶端請求張鐵牛的博客。

2.服務首先會請求redis,查看請求的內(nèi)容是否存在。

3.redis將請求結(jié)果返回給服務,如果返回的結(jié)果有數(shù)據(jù)則執(zhí)行7;如果沒有數(shù)據(jù)則會繼續(xù)往下執(zhí)行。

4.服務從數(shù)據(jù)庫中查詢請求的數(shù)據(jù)。

5.數(shù)據(jù)庫將查詢的結(jié)果返回給服務。

6.如果數(shù)據(jù)庫有返回數(shù)據(jù),則將返回的結(jié)果添加到redis。

7.將請求到的數(shù)據(jù)返回給客戶端。

2. 緩存穿透

2.1描述

通過接口訪問一個緩存和數(shù)據(jù)庫都不存在的數(shù)據(jù)。

因為服務出于容錯考慮,當請求從持久層查不到數(shù)據(jù)則不寫入緩存,這將導致請求這個不存在的數(shù)據(jù)每次都要到持久層去查詢,失去了緩存的意義。

此時,緩存起不到保護后端持久層的意義,就像被穿透了一樣。導致數(shù)據(jù)庫存在被打掛的風險。

2.2 解決方案

1.接口請求參數(shù)的校驗。對請求的接口進行鑒權(quán),數(shù)據(jù)合法性的校驗等;比如查詢的userId不能是負值或者包含非法字符等。

2.當數(shù)據(jù)庫返回空值時,將空值緩存到redis,并設置合理的過期時間。

3.布隆過濾器。使用布隆過濾器存儲所有可能訪問的 key,不存在的 key 直接被過濾,存在的 key 則再進一步查詢緩存和數(shù)據(jù)庫。

3. 緩存擊穿

3.1 描述

某個熱點 key,在緩存過期的一瞬間,同時有大量的請求打進來,由于此時緩存過期了,所以請求最終都會走到數(shù)據(jù)庫,造成瞬時數(shù)據(jù)庫請求量大、壓力驟增,導致數(shù)據(jù)庫存在被打掛的風險。

3.2 解決方案

1.加互斥鎖。當熱點key過期后,大量的請求涌入時,只有第一個請求能獲取鎖并阻塞,此時該請求查詢數(shù)據(jù)庫,并將查詢結(jié)果寫入redis后釋放鎖。后續(xù)的請求直接走緩存。

2.設置緩存不過期或者后臺有線程一直給熱點數(shù)據(jù)續(xù)期。

4. 緩存雪崩

4.1 描述

大量的熱點數(shù)據(jù)過期時間相同,導致數(shù)據(jù)在同一時刻集體失效。造成瞬時數(shù)據(jù)庫請求量大、壓力驟增,引起雪崩,導致數(shù)據(jù)庫存在被打掛的風險。

4.1 解決方案

1.將熱點數(shù)據(jù)的過期時間打散。給熱點數(shù)據(jù)設置過期時間時加個隨機值。

2.加互斥鎖。當熱點key過期后,大量的請求涌入時,只有第一個請求能獲取鎖并阻塞,此時該請求查詢數(shù)據(jù)庫,并將查詢結(jié)果寫入redis后釋放鎖。后續(xù)的請求直接走緩存。

3.設置緩存不過期或者后臺有線程一直給熱點數(shù)據(jù)續(xù)期。

5. 布隆過濾器

5.1 描述

布隆過濾器是防止緩存穿透的方案之一。布隆過濾器主要是解決大規(guī)模數(shù)據(jù)下不需要精確過濾的業(yè)務場景,如檢查垃圾郵件地址,爬蟲URL地址去重, 解決緩存穿透問題等。

布隆過濾器:在一個存在一定數(shù)量的集合中過濾一個對應的元素,判斷該元素是否一定不在集合中或者可能在集合中。它的優(yōu)點是空間效率和查詢時間都比一般的算法要好的多,缺點是有一定的誤識別率和刪除困難。

5.2 數(shù)據(jù)結(jié)構(gòu)

布隆過濾器是基于bitmap和若干個hash算法實現(xiàn)的。如下圖所示:

1.元素tie經(jīng)過hash1,hash2,hash3運算出對應的三個值落到了數(shù)組下標為4,6,8的位置上,并將其位置的默認值0,修改成1

2.元素niu同理落到了數(shù)組下標為1,3,4的位置上,并將其位置的默認值0,修改成1

此時bitmap中已經(jīng)存儲了tie,niu數(shù)據(jù)元素。

當請求想通過布隆過濾器判斷tie元素在程序中是否存在時,通過hash運算結(jié)果到數(shù)組對應下標位置上發(fā)現(xiàn)值已經(jīng)都被置為1,此時返回true。

5.3 “一定不在集合中”

如圖所示:

​ 元素zhang通過布隆過濾器判斷時,下標0,2都為0,則直接返回false。

也就是當判斷不在bitmap中的元素時,經(jīng)過hash運算得到的結(jié)果在bitmap中只要有一個為0,則該數(shù)據(jù)一定不存在。

5.4 “可能在集合中”

如圖所示:

​ 元素shuaibi通過布隆過濾器判斷時,hash運算的結(jié)果落到了下標1,3,8上,此時對應下標位置的值都為1,則直接返回true。

這下就尷尬了,因為實際程序中并沒有數(shù)據(jù)shuaibi,但布隆過濾器返回的結(jié)果顯示有這個元素。這就是布隆過濾器的缺點,存在誤判情況。

5.5 ”刪除困難“

為什么布隆過濾器刪除困難呢,如圖所示:

如果刪除了“tie”元素,4號位被置為0,則會影響niu元素的判斷,因為4號位為0,進行數(shù)據(jù)校驗時返回0,則會認為程序中沒有niu元素。

那小伙伴會問,4號位不置為0,行不行?

如果刪除了元素,hash碰撞的數(shù)組下標不置為0,那么如果繼續(xù)驗證該元素的話,布隆過濾器會繼續(xù)返回true,但實際上元素已經(jīng)刪除了。

所以布隆過濾器數(shù)據(jù)刪除困難,如果要刪除的話,可以參考Counting Bloom Filter

5.6 為什么不使用HashMap呢?

如果用HashSet或Hashmap存儲的話,每一個用戶ID都要存成int,占4個字節(jié)即32bit。而一個用戶在bitmap中只需要1個bit,內(nèi)存節(jié)省了32倍。

并且大數(shù)據(jù)量會產(chǎn)生大量的hash沖突,結(jié)果就是產(chǎn)生hash沖突的數(shù)據(jù),仍然會進行遍歷挨個比對(即使轉(zhuǎn)成紅黑樹),這樣對內(nèi)存空間和查詢效率的提升,仍然是有限的。

當然:數(shù)據(jù)量不大時,盡管使用。而且hashmap方便進行CRUD😂

到此這篇關(guān)于詳解緩存穿透/擊穿/雪崩原理及其解決方案的文章就介紹到這了,更多相關(guān)緩存穿透/擊穿/雪崩內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于 Redis 的 JWT令牌失效處理方案(實現(xiàn)步驟)

    基于 Redis 的 JWT令牌失效處理方案(實現(xiàn)步驟)

    當用戶登錄狀態(tài)到登出狀態(tài)時,對應的JWT的令牌需要設置為失效狀態(tài),這時可以使用基于Redis 的黑名單方案來實現(xiàn)JWT令牌失效,本文給大家分享基于 Redis 的 JWT令牌失效處理方案,感興趣的朋友一起看看吧
    2024-03-03
  • Redis 過期鍵刪除策略的實現(xiàn)示例

    Redis 過期鍵刪除策略的實現(xiàn)示例

    Redis的過期數(shù)據(jù)刪除策略主要有三種,包括定時刪除、惰性刪除和定期刪除,本文主要介紹了Redis 過期鍵刪除策略的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • 壓縮列表犧牲速度來節(jié)省內(nèi)存,Redis是膨脹了嗎

    壓縮列表犧牲速度來節(jié)省內(nèi)存,Redis是膨脹了嗎

    這篇文章主要給大家解釋了Redis 當中的 ziplist(壓縮列表)犧牲速度來節(jié)省內(nèi)存的原因,希望大家能夠喜歡
    2021-02-02
  • Redis優(yōu)惠券秒殺解決方案

    Redis優(yōu)惠券秒殺解決方案

    這篇文章主要介紹了Redis解決優(yōu)惠券秒殺應用案例,本文先講了搶購問題,指出其中會出現(xiàn)的多線程問題,提出解決方案采用悲觀鎖和樂觀鎖兩種方式進行實現(xiàn),然后發(fā)現(xiàn)在搶購過程中容易出現(xiàn)一人多單現(xiàn)象,需要的朋友可以參考下
    2022-12-12
  • 詳解redis集群的三種方式

    詳解redis集群的三種方式

    Redis三種集群方式分別是主從復制,哨兵模式,Cluster集群,這篇文章主要介紹了redis集群的三種方式,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • redis中opsForList().range()的使用方法詳解

    redis中opsForList().range()的使用方法詳解

    這篇文章主要給大家介紹了關(guān)于redis中opsForList().range()的使用方法,文中通過實例代碼以及圖文介紹的非常詳細,對大家學習或者使用redis具有一定的參考學習價值,需要的朋友可以參考下
    2023-03-03
  • Redis中Scan命令的踩坑實錄

    Redis中Scan命令的踩坑實錄

    這篇文章主要給大家介紹了關(guān)于Redis中Scan命令踩坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-07-07
  • Redis接口訪問優(yōu)化的方法步驟

    Redis接口訪問優(yōu)化的方法步驟

    本文基于之前的Redis接口訪問進行優(yōu)化,引入了接口防抖功能,通過時間段參數(shù)限制接口調(diào)用頻率,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-10-10
  • 淺談redis緩存在項目中的使用

    淺談redis緩存在項目中的使用

    最近由于項目需要,在系統(tǒng)緩存服務部分上用到了redis,本文就淺談下在redis緩存在項目中的使用,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 淺談Redis?中的過期刪除策略和內(nèi)存淘汰機制

    淺談Redis?中的過期刪除策略和內(nèi)存淘汰機制

    本文主要介紹了Redis?中的過期刪除策略和內(nèi)存淘汰機制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04

最新評論