今天來分享一下redis幾道常見的面試題:
回顧一下我們為什麼要用快取(redis):
現在有個問題,如果我們的快取掛掉了,這意味著我們的全部請求都跑去資料庫了。
在前面學習我們都知道redis不可能把所有的資料都快取起來(記憶體昂貴且有限),所以redis需要對資料設定過期時間,並採用的是惰性刪除+定期刪除兩種策略對過期鍵刪除。redis對過期鍵的策略+持久化
如果快取資料設定的過期時間是相同的,並且redis恰好將這部分資料全部刪光了。這就會導致在這段時間內,這些快取同時失效,全部請求到資料庫中。
這就是快取雪崩:
快取雪崩如果發生了,很可能就把我們的資料庫搞垮,導致整個服務癱瘓!
對於「對快取資料設定相同的過期時間,導致某段時間內快取失效,請求全部走資料庫。」這種情況,非常好解決:
對於「redis掛掉了,請求全部走資料庫」這種情況,我們可以有以下的思路:
比如,我們有一張資料庫表,id都是從1開始的(正數):
但是可能有黑客想把我的資料庫搞垮,每次請求的id都是負數。這會導致我的快取就沒用了,請求全部都找資料庫去了,但資料庫也沒有這個值啊,所以每次都返回空出去。
快取穿透是指查詢乙個一定不存在的資料。由於快取不命中,並且出於容錯考慮,如果從資料庫查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到資料庫去查詢,失去了快取的意義。這就是快取穿透:
快取穿透如果發生了,也可能把我們的資料庫搞垮,導致整個服務癱瘓!
解決快取穿透也有兩種方案:
上面講快取穿透的時候也提到了:如果從資料庫查不到資料則不寫入快取。
一般我們對讀操作的時候有這麼乙個固定的套路:
如果僅僅查詢的話,快取的資料和資料庫的資料是沒問題的。但是,當我們要更新時候呢?各種情況很可能就造成資料庫和快取的資料不一致了。
從理論上說,只要我們設定了鍵的過期時間,我們就能保證快取和資料庫的資料最終是一致的。因為只要快取資料過期了,就會被刪除。隨後讀的時候,因為快取裡沒有,就可以查資料庫的資料,然後將資料庫查出來的資料寫入到快取中。
除了設定過期時間,我們還需要做更多的措施來盡量避免資料庫與快取處於不一致的情況發生。
一般來說,執行更新操作時,我們會有兩種選擇:
首先,要明確的是,無論我們選擇哪個,我們都希望這兩個操作要麼同時成功,要麼同時失敗。所以,這會演變成乙個分布式事務的問題。
所以,如果原子性被破壞了,可能會有以下的情況:
如果第一步已經失敗了,我們直接返回exception出去就好了,第二步根本不會執行。下面我們具體來分析一下吧。
操作快取也有兩種方案:
一般我們都是採取刪除快取快取策略的,原因如下:
高併發環境下,無論是先運算元據庫還是後運算元據庫而言,如果加上更新快取,那就更加容易導致資料庫與快取資料不一致問題。(刪除快取直接和簡單很多)
如果每次更新了資料庫,都要更新快取【這裡指的是頻繁更新的場景,這會耗費一定的效能】,倒不如直接刪除掉。等再次讀取時,快取裡沒有,那我到資料庫找,在資料庫找到再寫到快取裡邊(體現懶載入)
基於這兩點,對於快取在更新時而言,都是建議執行刪除操作!
正常的情況是這樣的:
如果原子性被破壞了:
如果在高併發的場景下,出現資料庫與快取資料不一致的概率特別低,也不是沒有:
要達成上述情況,還是說一句概率特別低:
因為這個條件需要發生在讀快取時快取失效,而且併發著有乙個寫操作。而實際上資料庫的寫操作會比讀操作慢得多,而且還要鎖表,而讀操作必需在寫操作前進入資料庫操作,而又要晚於寫操作更新快取,所有的這些條件都具備的概率基本並不大。對於這種策略,其實是一種設計模式:
cache aside pattern
刪除快取失敗的解決思路:
正常情況是這樣的:
如果原子性被破壞了:
看起來是很美好,但是我們在併發場景下分析一下,就知道還是有問題的了:
所以也會導致資料庫和快取不一致的問題。
併發下解決資料庫與快取不一致的思路:
我們可以發現,兩種策略各自有優缺點:
先更新資料庫,再刪除快取(cache aside pattern
設計模式)
可以用databus或者阿里的canal監聽binlog進行更新。
如何保證快取與資料庫雙寫時的資料一致性?
分布式之資料庫和快取雙寫一致性方案解析
cache aside pattern
這是幾道redis常見的面試題,希望大家看完有所幫助,順利拿到offer!
面試前必須要知道的Redis面試題
回顧前面 從零單排學redis 青銅 從零單排學redis 從零單排學redis 從零單排學redis 鉑金一 從零單排學redis 鉑金二 redis 今天來分享一下redis幾道常見的面試題 如何解決快取雪崩?如何解決快取穿透?如何保證快取與資料庫雙寫時一致的問題?一 快取雪崩 1.1什麼是快取...
面試前必須要知道的Redis面試題
前言 文字已收錄至我的github倉庫,歡迎star 回顧前面 從零單排學redis 青銅 從零單排學redis 從零單排學redis 從零單排學redis 鉑金一 從零單排學redis 鉑金二 今天來分享一下redis幾道常見的面試題 如何解決快取雪崩?如何解決快取穿透?如何保證快取與資料庫雙寫時...
面試前必須要知道的Redis面試題
回顧前面 今天來分享一下redis幾道常見的面試題 回顧一下我們為什麼要用快取 redis 現在有個問題,如果我們的快取掛掉了,這意味著我們的全部請求都跑去資料庫了。在前面學習我們都知道redis不可能把所有的資料都快取起來 記憶體昂貴且有限 所以redis需要對資料設定過期時間,並採用的是惰性刪除...