轉載:面試前必需要知道的Redis面試題html
今天來分享一下Redis幾道常見的面試題:git
回顧一下咱們爲何要用緩存(Redis):github
如今有個問題,若是咱們的緩存掛掉了
,這意味着咱們的所有請求都跑去數據庫了。面試
可是Redis不可能把全部的數據都緩存起來(內存昂貴且有限),因此Redis須要對數據設置過時時間,並採用的是惰性刪除
+ 按期刪除
兩種策略對過時數據進行清理。redis
若是緩存數據設置的過時時間是相同
的,而且Redis剛好將這部分數據所有刪光了。這就會致使在這段時間內,這些緩存同時失效
,所有請求到數據庫中。shell
這就可能致使緩存雪崩
:數據庫
緩存雪崩若是發生了,極可能就把咱們的數據庫搞垮
,致使整個服務癱瘓
!segmentfault
對於「對緩存數據設置相同的過時時間,致使某段時間內緩存失效,請求所有走數據庫。」這種狀況,很是好解決:設計模式
減小緩存在同一時間過時
。對於「Redis掛掉了,請求所有走數據庫」這種狀況,咱們能夠有如下的思路:
好比,咱們有一張數據庫表,ID都是從1開始的(正數):
可是可能有黑客想把個人數據庫搞垮,每次請求的ID都是負數。這會致使個人緩存就沒用了,請求所有都找數據庫去了,但數據庫也沒有這個值啊,因此每次都返回空出去。
緩存穿透是指查詢一個必定
不存在的數據
。因爲緩存不命中,而且出於容錯考慮,若是從數據庫查不到數據則不寫入緩存
,這將致使這個不存在的數據每次請求都要到數據庫去查詢
,失去了緩存的意義。
這就是緩存穿透
:
緩存穿透若是發生了,也可能把咱們的數據庫搞垮
,致使整個服務癱瘓!
解決緩存穿透也有兩種方案:
提早攔截
,不合法就不讓這個請求到數據庫層!空對象設置到緩存裏邊去
。下次再請求的時候,就能夠從緩存裏邊獲取了(這種狀況咱們通常會將空對象設置一個較短的過時時間)。上面講緩存穿透的時候也提到了:若是從數據庫查不到數據則不寫入緩存。
通常咱們對讀操做的時候有這麼一個固定的套路:
若是僅僅查詢的話,緩存的數據和數據庫的數據是沒問題的。可是,當咱們要更新
的時候呢?各類狀況極可能就形成數據庫和緩存的數據不一致了。
從理論上說,只要咱們設置了鍵的過時時間,咱們就能保證緩存和數據庫的數據最終是一致
的。由於只要緩存數據過時了,就會被刪除。隨後讀的時候,由於緩存裏沒有,就能夠查數據庫的數據,而後將數據庫查出來的數據寫入到緩存中。
除了設置過時時間,咱們還須要作更多的措施來儘可能避免數據庫與緩存處於不一致的狀況發生。
通常來講,執行更新操做時,咱們會有兩種選擇:
首先,要明確的是,不管咱們選擇哪一個,咱們都但願這兩個操做要麼同時成功,要麼同時失敗
。因此,這會演變成一個分佈式事務
的問題。
因此,若是原子性被破壞了,可能會有如下的狀況:
若是第一步已經失敗了,咱們直接返回Exception出去就行了,第二步根本不會執行。
下面咱們具體來分析一下吧。
操做緩存也有兩種方案:
通常咱們都是採起刪除緩存緩存策略
的,緣由以下:
基於這兩點,對於緩存在更新時而言,都是建議執行刪除操做
!
正常的狀況是這樣的:
若是原子性被破壞了:
數據庫裏是新數據,而緩存裏是舊數據
。若是在高併發的場景下,出現數據庫與緩存數據不一致的機率特別低,也不是沒有:
要達成上述狀況,仍是說一句機率特別低
由於這個條件須要發生在讀緩存時緩存失效,並且併發着有一個寫操做。而實際上數據庫的寫操做會比讀操做慢得多,並且還要鎖表,而讀操做必需在寫操做前進入數據庫操做,而又要晚於寫操做更新緩存,全部的這些條件都具有的機率基本並不大。
對於這種策略,實際上是一種設計模式:Cache Aside Pattern
刪除緩存失敗的解決思路:
正常狀況是這樣的:
若是原子性被破壞了:
看起來是很美好,可是咱們在併發場景下分析一下,就知道仍是有問題的了:
因此也會致使數據庫和緩存不一致的問題。
併發下解決數據庫與緩存不一致的思路:
刪除緩存
、修改數據庫
、讀取緩存
等的操做積壓到隊列
裏邊,實現串行化
。咱們能夠發現,兩種策略各自有優缺點:
先刪除緩存,再更新數據庫;在高併發下表現不如意,在原子性被破壞時表現優異
先更新數據庫,再刪除緩存(Cache Aside Pattern設計模式);在高併發下表現優異,在原子性被破壞時表現不如意
能夠用databus或者阿里的canal監聽binlog進行更新。
緩存更新的套路 https://coolshell.cn/articles/17416.html
如何保證緩存與數據庫雙寫時的數據一致性? https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/redis-consistence.md
分佈式之數據庫和緩存雙寫一致性方案解析 https://zhuanlan.zhihu.com/p/48334686
Cache Aside Pattern http://www.javashuo.com/article/p-cvhoacmi-v.html