雙重檢測同步鎖 防止Redis快取穿透

2021-08-15 01:46:04 字數 1136 閱讀 5428

快取穿透:

注:

上面三個圖會有什麼問題呢?

我們在專案中使用快取通常都是先檢查快取中是否存在,如果存在直接返回快取內容,如果不存在就直接查詢資料庫然後再快取查詢結果返回。這個時候如果我們查詢的某乙個資料在快取中一直不存在,就會造成每一次請求都查詢db,這樣快取就失去了意義,在流量大時,可能db就掛掉了。

那這種問題有什麼好辦法解決呢?

要是有人利用不存在的key頻繁攻擊我們的應用,這就是漏洞。

有乙個比較巧妙的作法是,可以將這個不存在的key預先設定乙個值。

比如,」key」 , 「&&」。

在返回這個&&值的時候,我們的應用就可以認為這是不存在的key,那我們的應用就可以決定是否繼續等待繼續訪問,還是放棄掉這次操作。如果繼續等待訪問,過乙個時間輪詢點後,再次請求這個key,如果取到的值不再是&&,則可以認為這時候key有值了,從而避免了透傳到資料庫,從而把大量的類似請求擋在了快取之中。

快取併發:

有時候如果**併發訪問高,乙個快取如果失效,可能出現多個程序同時查詢db,同時設定快取的情況,如果併發確實很大,這也可能造成db壓力過大,還有快取頻繁更新的問題。

我現在的想法是對快取查詢加鎖,如果key不存在,就加鎖,然後查db入快取,然後解鎖;其他程序如果發現有鎖就等待,然後等解鎖後返回資料或者進入db查詢。

這種情況和剛才說的預先設定值問題有些類似,只不過利用鎖的方式,會造成部分請求等待。

根據快取併發這種思想,寫了以下的雙重檢測同步鎖:

@service

public class studentserviceimpl implements studentservice else

}} else

return studentlist;}}

雙重檢測鎖單例模式指令重排問題

解決方案 相信大多數同學在面試當中都遇到過手寫單例模式的題目,那麼如何寫乙個完美的單例是面試者需要深究的問題,因為乙個嚴謹的單例模式說不定就直接決定了面試結果,今天我們就要來講講看似執行緒安全的雙重檢測鎖單例模式中可能會出現的指令重排問題。乍一看下面單例模式沒啥問題,還加了同步鎖保證執行緒安全,從表...

redis記憶體鎖,PHP防止併發操作

1 redis鎖 獲取鎖 param string key 鎖標識 param int expire 鎖過期時間 return boolean public function lock key,expire 5 return is lock?true false 釋放鎖 param string k...

單例模式的雙重檢測鎖與volatile禁止重排

public class demo public static demo getinstance return instance 上面單例實現方式在單執行緒訪問下沒有問題,但是在併發訪問時,會產生多個物件。如程式啟動 a執行緒獲取instance執行完if判斷為null後,執行緒b獲取到cpu執行權...