緩存穿透
很多項目在使用Redis或其他緩存框架的時候,都是先查詢緩存,查詢不的話再查詢數據庫,查到之后再放到內存中;如果一個key值本身就不存在,那么每一次都會查詢數據庫,也就是常說的【緩存穿透】。
應對方法:
如果在Redis中查詢不到,并且查詢數據庫也沒有結果,那么就將這個key寫入到Redis中,value=空,并設置一個超時過期時間,例如五分鐘,那么五分鐘以內的對這個可以的所有查詢就可以攔截下來,如果數據庫有key對應的數據了,那么五分鐘后Redis中的緩存過期,會訪問數據庫并加載緩存;但是如果被惡意攻擊,每次請求的key都不相同且不存在,那么依然會穿透到數據庫;
布隆過濾器:將可能存在的數據Hash到一個足夠大的bitmap上,它可以告訴你 “某個key一定不存在或者可能存在”,一個一定不存在的數據會被bitmap攔截。
緩存雪崩很多時候,Redis中的緩存是要設置過期時間的,假如Redis中的數據,過期時間都設置成一樣的,那么到了時間之后,全部緩存過期失效,下一秒所有的請求都會訪問數據庫,那么數據庫可能因為訪問量多大導致“崩潰”,這就是緩存雪崩。
應對方法:
最暴力的解決辦法,緩存不設置自動過期時間,只要緩存不崩,數據庫就不會崩。
另外一個辦法,就是讓緩存過期時間不那么一致,比如一批緩存數據24小時后過期,那么就在這個基礎上,每條緩存的過期時間前后隨機1-6000秒(1-10分鐘)。
緩存并發大多數時候,我們的程序訪問Redis都不可能是單線程,那么當多個Client并發對Redis進行set key操作的時候,可能會產生一些問題;其實Redis本身是單線程的,這種時候會按照先后順序進行操作;或者把操作放在隊列中,按順序執行;
但比如這種情況:
token過期,有兩個線程都去重新獲取token;
線程1獲取token1;
線程2獲取到token2,此時token1過期;
線程1把token1放到Redis,再拿著token1去調用服務,發現過期了,繼續去請求token3,此時token2過期;
線程2把token2放到Redis,再拿著token2去調用服務,發現過期了,繼續去請求token4,此時token3過期;
... ...
這就需要我們在更新緩存的時候,做一些控制了。
我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。