緩存相關-先埋個坑後續填補

說到緩存,離不開一些概念:緩存擊穿,緩存穿透,緩存雪崩。談談我我的對這些概念的理解吧。web

  • 緩存穿透

請求沒有訪問到緩存,而是直接訪問到了數據庫層面,可是數據庫層面也沒有返回數據。
這種狀況不少都是惡意攻擊的時候出現的。複製代碼

場景:有個商品詳情的接口/goods/{id},通常id都是數據庫自增的,從1開始,如/goods/1。假若有個/goods/-1的請求過來了, 因爲數據庫中不存在-1的商品信息,天然在緩存裏也不會去緩存這樣的數據,所以這樣的請求就可能會直接訪問到數據庫,當有大批量的相似請求併發訪問的時候,就有可能會給數據庫形成壓力,致使性能瓶頸。數據庫

解決辦法

1. 參數校驗。好比校驗id是否合法,id < 1的直接過濾掉。緩存

2. 降級方案是針對這些不合理的id作緩存,即,在數據庫層訪問結束後假如沒有查到數據,則把這些id緩存下來,相似於作黑名單id同樣,等下次再來訪問的時候先檢查id是否在黑名單id列表裏,在的話就不要走後面的流程,直接返回。這種方案的缺點是隻能攔截id相同的,假如一直用不一樣的id去訪問的話,那黑名單id列表會不斷的增大,致使緩存吃緊bash

  • 緩存擊穿

請求訪問過來的時候,恰好緩存處於失效狀態,致使高併發的請求訪問到了數據庫層面,數據庫有可能會所以而資源緊張。複製代碼

場景:商品詳情的請求 /goods/1 訪問的時候,恰好 id=1 的緩存處於失效狀態,致使該請求直接訪問了數據庫,數據庫返回了 id=1數據 併發

解決辦法

1. 不設置緩存失效時間,異步刷新緩存數據。即,當有請求過來的時候,檢查緩存的有效狀態,假如緩存狀態是已失效,能夠經過發送異步消息給後臺,經過後臺去刷新緩存數據。本次請求依舊返回緩存中的失效數據。app

2. 能夠設置緩存失效時間,可是經過加鎖的方式刷新數據。即,當請求過來的時候,假如緩存中沒有數據,則經過加鎖的方式讓請求排隊,只容許一個請求去訪問到數據庫,防止併發訪問,數據庫返回數據後存到緩存當中,釋放鎖,第二個請求進來的時候判斷是否緩存中已有數據,有的話直接讀取。這種方案可能須要限制併發次數,避免大量請求排隊致使web容器的鏈接池爆滿,影響別的業務請求。異步

  • 緩存雪崩
指的是大量緩存在同一時刻失效的現象,致使各類請求訪問的時候都沒有讀取到緩存的數據,而是全都訪問了數據庫。複製代碼

場景:同時有商品數據、訂單數據等緩存數據在同一瞬間失效,用戶的訪問請求全都直接訪問到了數據庫,數據庫可能在瞬時承受着極高的併發訪問。 
高併發

解決辦法

1. 各類業務數據在設置緩存失效時間的時候,不要選擇相同的失效時間,能夠選擇錯峯失效的方式,好比選擇夜深人靜訪問量少的時候失效,或者給失效時間再加個隨機值,不要在整點時刻失效,好比選擇在xx點xx分23秒的時候失效,避免緩存數據瞬間大量失效。性能

2. 緩存不要失效,異步刷新數據。ui

  • 總結

緩存穿透和緩存擊穿有點相似,不一樣之處在於緩存穿透不少狀況下是惡意訪問致使的,而緩存擊穿是內部緩存策略致使的。

緩存擊穿和緩存雪崩都是內部緩存策略致使的,不一樣之處在於緩存擊穿是某個點上的緩存問題,而緩存雪崩是一大片一大面的。點和麪的區別。

相關文章
相關標籤/搜索