隨着系統訪問量的提升,複雜度的提高,響應性能成爲一個重點的關注點。而緩存的使用成爲一個重點。redis 做爲緩存中間件的一個佼佼者,成爲了面試必問項目。面試
本文分享一下Redis幾道常見的面試題:redis
若是咱們的緩存掛掉了,這意味着咱們的所有請求都跑去數據庫了。數據庫
咱們都知道Redis不可能把全部的數據都緩存起來(內存昂貴且有限),因此Redis須要對數據設置過時時間,並採用的是惰性刪除+按期刪除兩種策略對過時鍵刪除。緩存
若是緩存數據設置的過時時間是相同的,而且Redis剛好將這部分數據所有刪光了。這就會致使在這段時間內,這些緩存同時失效,所有請求到數據庫中。架構
這就是緩存雪崩:Redis掛掉了,請求所有走數據庫。性能
緩存雪崩若是發生了,極可能就把咱們的數據庫搞垮,致使整個服務癱瘓!spa
在緩存的時候給過時時間加上一個隨機值,這樣就會大幅度的減小緩存在同一時間過時。中間件
對於「Redis掛掉了,請求所有走數據庫」這種狀況,咱們能夠有如下的思路:對象
事發前:實現Redis的高可用(主從架構+Sentinel 或者Redis Cluster),儘可能避免Redis掛掉這種狀況發生。blog
事發中:萬一Redis真的掛了,咱們能夠設置本地緩存(ehcache)+限流(hystrix),儘可能避免咱們的數據庫被幹掉(起碼能保證咱們的服務仍是能正常工做的)
事發後:redis持久化,重啓後自動從磁盤上加載數據,快速恢復緩存數據。
緩存穿透是指查詢一個必定不存在的數據。因爲緩存不命中,而且出於容錯考慮,若是從數據庫查不到數據則不寫入緩存,這將致使這個不存在的數據每次請求都要到數據庫去查詢,失去了緩存的意義。
這就是緩存穿透:
請求的數據在緩存大量不命中,致使請求走數據庫。
緩存穿透若是發生了,也可能把咱們的數據庫搞垮,致使整個服務癱瘓!
解決緩存穿透也有兩種方案:
因爲請求的參數是不合法的(每次都請求不存在的參數),因而咱們可使用布隆過濾器(BloomFilter)或者壓縮filter提早攔截,不合法就不讓這個請求到數據庫層!
當咱們從數據庫找不到的時候,咱們也將這個空對象設置到緩存裏邊去。下次再請求的時候,就能夠從緩存裏邊獲取了。
這種狀況咱們通常會將空對象設置一個較短的過時時間。
若是咱們的數據在緩存裏邊有,那麼就直接取緩存的。
若是緩存裏沒有咱們想要的數據,咱們會先去查詢數據庫,而後將數據庫查出來的數據寫到緩存中。最後將數據返回給請求。
若是僅僅查詢的話,緩存的數據和數據庫的數據是沒問題的。可是,當咱們要更新時候呢?各類狀況極可能就形成數據庫和緩存的數據不一致了。
這裏不一致指的是:數據庫的數據跟緩存的數據不一致
從理論上說,只要咱們設置了鍵的過時時間,咱們就能保證緩存和數據庫的數據最終是一致的。由於只要緩存數據過時了,就會被刪除。隨後讀的時候,由於緩存裏沒有,就能夠查數據庫的數據,而後將數據庫查出來的數據寫入到緩存中。
除了設置過時時間,咱們還須要作更多的措施來儘可能避免數據庫與緩存處於不一致的狀況發生。