隨著系統訪問量的提高,複雜度的提公升,響應效能成為乙個重點的關注點。而快取的使用成為乙個重點。
如果我們的快取掛掉了,這意味著我們的全部請求都跑去資料庫了。
我們都知道redis不可能把所有的資料都快取起來(記憶體昂貴且有限),所以redis需要對資料設定過期時間,並採用的是惰性刪除 + 定期刪除兩種策略對過期鍵刪除。
如果快取資料設定的過期時間是相同的,並且redis恰好將這部分資料全部刪光了。這就會導致在這段時間內,這些快取同時失效,全部請求到資料庫中。
這就是快取雪崩:redis掛掉了,請求全部走資料庫。
快取雪崩如果發生了,很可能就把我們的資料庫搞垮,導致整個服務癱瘓!
在快取的時候給過期時間加上乙個隨機值,這樣就會大幅度的減少快取在同一時間過期。
對於「redis掛掉了,請求全部走資料庫」這種情況,我們可以有以下的思路:
事發前:實現redis的高可用(主從架構+sentinel 或者redis cluster),盡量避免redis掛掉這種情況發生。
事發中:萬一redis真的掛了,我們可以設定本地快取(ehcache)+限流(hystrix),盡量避免我們的資料庫被乾掉(起碼能保證我們的服務還是能正常工作的)
事發後:redis持久化,重啟後自動從磁碟上載入資料,快速恢復快取資料。
快取穿透是指查詢乙個一定不存在的資料。由於快取不命中,並且出於容錯考慮,如果從資料庫查不到資料則不寫入快取
這將導致這個不存在的資料每次請求都要到資料庫去查詢,失去了快取的意義。
這就是快取穿透:請求的資料在快取大量不命中,導致請求走資料庫。
快取穿透如果發生了,也可能把我們的資料庫搞垮,導致整個服務癱瘓!
解決快取穿透也有兩種方案:
由於請求的引數是不合法的(每次都請求不存在的引數),於是我們可以使用布隆過濾器(bloomfilter)或者壓縮filter提前攔截,不合法就不讓這個請求到資料庫層!
當我們從資料庫找不到的時候,我們也將這個空物件設定到快取裡邊去。下次再請求的時候,就可以從快取裡邊獲取了。這種情況我們一般會將空物件設定乙個較短的過期時間。
如果我們的資料在快取裡邊有,那麼就直接取快取的。
如果快取裡沒有我們想要的資料,我們會先去查詢資料庫,然後將資料庫查出來的資料寫到快取中。最後將資料返回給請求。
如果僅僅查詢的話,快取的資料和資料庫的資料是沒問題的。但是,當我們要更新時候呢?各種情況很可能就造成資料庫和快取的資料不一致了。
這裡不一致指的是:資料庫的資料跟快取的資料不一致
從理論上說,只要我們設定了鍵的過期時間,我們就能保證快取和資料庫的資料最終是一致的。
因為只要快取資料過期了,就會被刪除。隨後讀的時候,因為快取裡沒有,就可以查資料庫的資料,然後將資料庫查出來的資料寫入到快取中。
除了設定過期時間,我們還需要做更多的措施來盡量避免資料庫與快取處於不一致的情況發生。
redis的穿透和雪崩
redis穿透 正常的執行路徑是這樣的,請求資料,首先會從redis快取中拿資料,如果快取沒有的話才去查資料庫,再寫到redis快取中。那麼如果有人請求一條根本不存在的資料時,redis裡面肯定沒有嘛,它就會去訪問資料庫,但是資料庫沒有,所以它也沒把資料寫回redis快取。所以它每次請求這個資料的時...
Redis的雪崩和穿透
redis穿透 正常的執行路徑是這樣的,請求資料,首先會從redis快取中拿資料,如果快取沒有的話才去查資料庫,再寫到redis快取中。那麼如果有人請求一條根本不存在的資料時,redis裡面肯定沒有嘛,它就會去訪問資料庫,但是資料庫沒有,所以它也沒把資料寫回redis快取。所以它每次請求這個資料的時...
redis的穿透和雪崩
快取穿透是指查詢乙個一定不存在的資料,由於快取是不命中時需要從資料庫查詢,查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到資料庫去查詢,造成快取穿透。如果快取集中在一段時間內失效,發生大量的快取穿透,所有的查詢都落在資料庫上,造成了快取雪崩。這個沒有完美解決辦法,但可以分析使用者行為,...