緩存擊穿
緩存擊穿,是指一個key很是熱點,在不停的扛着大併發,大併發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的大併發就穿破緩存,直接請求數據庫,就像在一個屏障上鑿開了一個洞。redis
那麼如何解決這個問題呢?數據庫
有不少種思路能夠解決這樣的問題,好比使緩存常駐內存,採用異步刷新等方法,這裏介紹使用分佈式鎖來解決這樣的問題。緩存
大致思路
- 1.咱們從緩存中獲取數據,若是獲取到數據則直接返回。
- 2.若是未從緩存中獲取到數據,就須要從數據庫中讀取,爲了防止大量併發直接訪問數據庫,就須要加上分佈式鎖,確保只有一個請求訪問數據庫。
- 3.當加鎖成功,作一下三步:1)從數據庫中讀取數據, 2)把數據寫入緩存, 3)刪除分佈式鎖。
- 4.若是加鎖沒有成功,則讓進程休眠一段時間,重複1步驟。
- 5.爲了防止意外狀況的發生,咱們須要設置一個閥值,當獲取緩存中的次數超過閥值時,直接退出程序,防止大量的併發被阻塞。
redis實現分佈式鎖
咱們這裏使用redis實現分佈式鎖,使用下面的語句實現bash
SET [KEY] [RAND_NUM] EX [LOCK_TIME] NX
複製代碼
- KEY: 鎖的鍵,根據實際狀況指定。
- RAND_NUM: 隨機數,防止因執行時間過長鎖失效,致使誤刪鎖的操做。
- EX: 表示設置此鎖的失效時間防止過時後死鎖。
- LOCK_TIME: 多少秒後過時。
- NX:表示若是次鎖不存在,則建立此鎖。
當鎖不存在時,redis會返回"ok",表示鎖建立成功,當鎖存在時,redis返回"NULL",咱們能夠根據返回值來肯定是否有建立成功。併發
使用場景
咱們從流程圖上能看到,更新緩存會致使併發線程阻塞。異步
這裏有兩個關鍵點會影響系統性能:分佈式
- 1.單個緩存併發數量越大,對系統性能影響越大。
- 2.更新單個緩存時間越長,對系統性能影響越大。
因此使用此方法使用場景是:非熱點的簡單緩存數據(併發小,更新時間短)。性能