天天看點

Spring Boot 進階-Spring Boot整合Redis實戰緩存穿透

作者:架構師面試寶典
Spring Boot 進階-Spring Boot整合Redis實戰緩存穿透

緩存的引入極大地提升了系統的整體的查詢效率和執行效率,但是也帶來了一些新的問題,其中不乏有很多經典的問題包括緩存穿透、緩存雪崩、緩存擊穿等等。對于這些問題,現在業界都有自己對應的解決方案,下面我們就來通過一個緩存穿透的例子來通過代碼實戰的方式來看看如何去解決緩存穿透問題。

在上篇文章中,我們介紹了在Spring Boot中如何整合Redis,這裡我們就通過上篇文章中的例子來實作緩存穿透案例。首先我們先來看看什麼是緩存穿透

緩存穿透

使用緩存的目的就是減少使用者流量對于資料庫的壓力。如下圖所示,當使用者請求需要查詢資料的時候,後端應用會先從緩存中進行查找,如果查詢到資料那麼就會直接傳回資料給使用者,這個時候整個的查詢流程就結束了。但是如果在緩存中沒有查詢到資料,則說明緩存中沒有緩存相關資料,這個時候就說明有其他的操作可能更新了資料,但是緩存中沒有,這個時候就需要到資料庫中進行查詢,如果擷取到了資料,那麼接下來完成兩個操作,第一個操作就是将擷取到的資料傳回給使用者,第二個操作就是按照規則将資料放入到緩存中。

Spring Boot 進階-Spring Boot整合Redis實戰緩存穿透

那麼在這個過程中,就會有這樣一個問題,如果在整個的查詢過程中,無論是緩存中,還是在資料庫中都沒有查詢到資料的時候,這個時候資料既不在資料庫中,也不會在緩存中,那麼如果這樣的請求大批量的進行請求的時候,就會導緻資料庫中有大量的查詢操作進入,這個時候就會導緻資料庫當機,拒絕服務。最終導緻資料庫伺服器的損壞。而這就是所謂的緩存穿透所帶來的問題。

那麼我們如何去解決這個問題呢?

緩存穿透解決方案

業界解決緩存穿透都有自己普遍的成熟解決方案。其中比較成熟的就是對如果在資料庫中沒有查詢到資料的時候的操作進行優化處理,最終達到解決緩存穿透問題解決的目的。

如果沒有查詢到資料,則将NULL傳回給前端用戶端的同時,将NULL也寫入到緩存中,并且對對應的Key值設定一個指定過期時間,這樣如果是存在網絡延遲的情況導緻資料沒有及時同步的時候,當Key過期了,也會從資料庫中更新新的資料存儲到緩存中。這種方案在一定程度上可以減輕資料庫的查詢壓力。

代碼實戰

建立一個模拟的使用者服務調用代碼如下

@RestController
public class CacheController {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private UserService userService;

    @GetMapping("/getInfo")
    public Object getInfo(@RequestParam("id") Integer id){

        User user = redisCache.getCacheObject(String.valueOf(id));

        if (user!=null){
            return user;
        }else {
            User user1 = userService.getUser(id);
            if (user1!=null){
                redisCache.setCacheObject(String.valueOf(id),user1);
            }else {
                redisCache.setCacheObject(String.valueOf(id),user1,10, TimeUnit.SECONDS);
            }
            return user1;
        }
    }
}
           

編寫好之後,我們啟動項目在浏覽器中通路指定使用者ID就會看到資料正常傳回,并且進行緩存存儲。否則則傳回NULL,并且在緩存中設定一個過期時間。當這個過期時間到了之後,緩存中的Key就會清除。如果資料庫存在了對應的id,這個時候就會進行正常的查詢邏輯将資料存儲到緩存中。當然在這個過程中還會涉及到其他的問題。例如緩存更新、緩存失效等問題。例如上面如果我們将所有的失效時間都設定成10秒,那麼在十秒之後,緩存中會有大量的KEY失效,就會帶來緩存雪崩等問題。是以這裡隻是通過一個小例子來展示如何解決緩存穿透問題。在整個緩存機制中還有各種各樣的問題等着我們去解決。

Spring Boot 進階-Spring Boot整合Redis實戰緩存穿透

總結

在實際開發過程中我們要根據業務的實際性質來決定使用什麼樣的緩存政策,對于一些長期不變的内容我們可以是采用手動清理緩存的操作,而對于一些需要實時更新的内容,我們就需要采用到其他的緩存政策來進行存儲,這樣才能更好的保證我們的使用者體驗。

繼續閱讀