Redis 快取穿透 擊穿 雪崩

2021-10-25 13:47:21 字數 2243 閱讀 5145

key對應的資料在db端並不存在。根據一般的業務設計流程和容錯考慮,請求過來先到redis中查詢,redis沒有再到db查詢,如果db也沒有資料就返回空結果給請求端。如此該key的每次查詢都會到達db,所以稱為"快取穿透"。若黑客利用此漏洞進行攻擊則可能壓垮資料庫。

引數校驗

最基本的就是首先做好引數校驗,一些不合法的引數請求直接丟擲異常資訊返回給客戶端。比如查詢的資料庫 id 不能小於 0、傳入的郵箱格式不對的時候直接返回錯誤訊息給客戶端等等。

限流針對ip,使用者名稱或者是token進行限流,限制該介面的訪問頻率

快取無效key

如果快取和資料庫都查不到某個 key 的資料就寫乙個到 redis 中去並設定過期時間,具體命令如下: set key value ex 10086 。這種方式可以解決請求的 key 變化不頻繁的情況,如果黑客惡意攻擊,每次構建不同的請求 key,會導致 redis 中快取大量無效的 key 。很明顯,這種方案並不能從根本上解決此問題。如果非要用這種方式來解決穿透問題的話,盡量將無效的 key 的過期時間設定短一點比如 1 分鐘。

另外,這裡多說一嘴,一般情況下我們是這樣設計 key 的: 表名:列名:主鍵名:主鍵值

布隆過濾器(redis中的資料結構,在redis深度歷險中有詳細介紹)

布隆過濾器是乙個非常神奇的資料結構,通過它我們可以非常方便地判斷乙個給定資料是否存在於海量資料中。我們需要的就是判斷 key 是否合法,有沒有感覺布隆過濾器就是我們想要找的那個「人」。

具體是這樣做的:

把所有可能存在的請求的值都存放在布隆過濾器中,當使用者請求過來,先判斷使用者發來的請求的值是否存在於布隆過濾器中。不存在的話,直接返回請求引數錯誤資訊給客戶端,存在的話才會走下面的流程。

加入布隆過濾器之後的快取處理流程圖如下。

但是,需要注意的是布隆過濾器可能會存在誤判的情況。總結來說就是: 布隆過濾器說某個元素存在,小概率會誤判。布隆過濾器說某個元素不在,那麼這個元素一定不在。

為什麼會出現誤判的情況呢? 我們還要從布隆過濾器的原理來說!

我們先來看一下,當乙個元素加入布隆過濾器中的時候,會進行哪些操作:

使用布隆過濾器中的雜湊函式對元素值進行計算,得到雜湊值(有幾個雜湊函式得到幾個雜湊值)。

根據得到的雜湊值,在位陣列中把對應下標的值置為 1。

我們再來看一下,當我們需要判斷乙個元素是否存在於布隆過濾器的時候,會進行哪些操作:

對給定元素再次進行相同的雜湊計算;

得到值之後判斷位陣列中的每個元素是否都為 1,如果值都為 1,那麼說明這個值在布隆過濾器中,如果存在乙個值不為1,說明該元素不在布隆過濾器中。

然後,一定會出現這樣一種情況:不同的字串可能雜湊出來的位置相同。 (可以適當增加位陣列大小或者調整我們的雜湊函式來降低概率)

參考:redis詳解(十三)------ redis布隆過濾器

key在db側存在資料,但redis中資料已過期。這種情況下,key在某些時間點被超高併發地訪問,是一種非常熱點的資料,彷彿一道閃電,故而形象的稱為"快取擊穿"。如果不對這種情況加以處理,大量併發請求可能會瞬間壓垮後端db。

使用互斥鎖(mutex key)

業界比較常用的做法,是使用mutex。簡單地來說,就是在快取失效的時候(判斷拿出來的值為空),不是立即去load db,而是先使用快取工具的某些帶成功操作返回值的操作(比如redis的setnx或者memcache的add)去set乙個mutex key,當操作返回成功時,再進行load db的操作並回設快取;否則,就重試整個get快取的方法。

這樣的方法是會有一些錯誤臨時結果返回,所以要根據具體特點場景來使用,比如秒殺場景,對大半併發請求結果的正確性不做限制

setnx,是「set if not exists」的縮寫,也就是只有不存在的時候才設定,可以利用它來實現鎖的效果。

快取擊穿是針對乙個key過期失效而言的,而快取雪崩是針對很多key快取失效而言的。大量key快取在同一時間段內失效或者快取服務不可用,導致後面的大量請求都直接落到了db上,造成資料庫短時間內要處理大量請求。這就好比雪崩一樣,摧枯拉朽之勢,資料庫的壓力可想而知,可能直接就被這麼多請求弄宕機了。

針對 redis 服務不可用的情況:

採用 redis 集群,避免單機出現問題整個快取服務都沒辦法使用。

限流,避免同時處理大量的請求。

針對熱點快取失效的情況:

設定不同的失效時間比如隨機設定快取的失效時間。

快取永不失效。

參考:redis 快取雪崩、擊穿、穿透

Redis快取穿透,穿透擊穿,快取雪崩

乙個一定不存在快取及查詢不到的資料,由於快取是不命中時被動寫的,並且出於容錯考慮,如果從儲存層查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到儲存層去查詢,失去了快取的意義。有很多種方法可以有效地解決快取穿透問題,最常見的則是採用布隆過濾器,將所有可能存在的資料雜湊到乙個足夠大的bit...

redis 快取穿透 擊穿 雪崩

介面層增加校驗,如使用者鑑權校驗,id做基礎校驗,id 0的直接攔截 從快取取不到的資料,在資料庫中也沒有取到,這時也可以將key value對寫為key null,快取有效時間可以設定短點,如30秒 設定太長會導致正常情況也沒法使用 這樣可以防止攻擊使用者反覆用同乙個id暴力攻擊 public o...

redis快取穿透,擊穿,雪崩

快取穿透 描述 快取穿透是指快取和資料庫中都沒有的資料,而使用者不斷發起請求,多來自於黑客攻擊。由於快取是不命中時被動寫的,並且出於容錯考慮,如果從儲存層查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到儲存層去查詢,失去了快取的意義。在流量大時,可能db就掛掉了,要是有人利用不存在的k...