數據緩存解決方案

前言

爲什麼要使用到緩存:主要還是由於數據庫的IO能力不足,因爲對於很多的數據數量還是很大,存儲在內存中會消耗很大的內存空間,而且對於很多的數據都需要持久化保存,所以大部分的數據需要存儲在硬盤上,但是我們都知道對於硬盤的讀寫速度還是十分有限的,對於單節點的Mysql通常可以處理5000次的讀取,和3000次的寫入
對於負載比較小的情況下,Mysql的響應時間通常可以在10ms以內完成,但是對於10000併發時候,要保證在10ms以內完成讀寫功能,對於任何的數據庫都不能夠做到。
所以這個時候就需要我們將數據一部分緩存在內存中,在讀取的時候儘可能少去直接訪問數據庫,減少對於數據庫的壓力的同時也能夠加快我們的訪問的速度。
這裏我們拋開前端瀏覽器的緩存,只考慮後臺的緩存,可以分爲數據庫緩存,持久層緩存,業務層緩存等。下面我們來進行一一介紹。

數據庫緩存

數據存在在內存中

在這裏插入圖片描述
我們可以將數據存在在內存中,這個時候對於請求來說,若是內存空間越大,對於緩存的命中就會越高,可以減少對於硬盤的訪問,畢竟對於內存的訪問速度來說就要比硬盤的讀寫要快得多,也就能加快訪問的速度。

數據庫業務數據分散存儲

之間我們都是隻用一塊硬盤,對於一塊硬盤的訪問和IO讀寫能力都是有限的,這個時候我們使用到多塊的硬盤,將數據的請求打在多塊硬盤上面,多塊硬盤的讀寫與IO能力較於一塊還是有很大的提升。

搭建數據庫集羣

對於單節點的MySql,線程的數量還是有限的,也只能夠支持有限的併發請求,對於高併發情況下,使用數據庫集羣也是數據庫解決緩存的最終方案。

數據庫緩存之查詢緩存

對於開啓了查詢緩存情況下,數據庫會把SELECT語句查詢到的結果保存到緩存中,可以在Mysql的配置文件中進行以下的配置

query_cache_size=2048M  # 緩存大小2G
query_cache_type=on # 開啓緩存

這裏我們需要注意的是對於MySql來說默認緩存是關閉的,但是我們想到不是說可以優化查詢嗎,爲什麼默認情況下卻又是關閉的呢?
因爲我們可能在一條

select * from student where classs like '2020%'

語句中查詢學生表的所有情況,對於查詢班級可能會有上百名學生,但是若是學生的,成績進行了更改,那麼此時這個緩存中的數據就會全部失效,這個時候也就增大了IO的負載,所以不建議開啓查詢緩存。

持久層緩存

對於Hibernate和MyBatis框架而言都有支持緩存的技術,具體分爲一級緩存和二級緩存。

  • 一級緩存是會話級別的緩存,Session關閉,緩存就會失效(查詢緩存);
  • 二級緩存就是引入第三方的存儲機制緩存數據(是存儲與框架之外)。

二級緩存

Mybatis支持多種的二級緩存技術,EHCache,Redis,Simple等等,同時對於Spring框架的Cache模塊,可以管理MyBatis的二級緩存。下面我們來具體演示一下如何配置與使用二級緩存。

配置Redis二級緩存

在配置文件中加上對應配置信息

既然需要Sping框架的Cache支持,我們在配置文件中加上以下的配置
對於type字段表示緩存內型是什麼這裏是redis表示爲redis類型。
cache-names: student student 表示對於student模塊開啓緩存處理將來還要緩存什麼數據,就在student後面加上逗號再加上具體的緩存對象。
在這裏插入圖片描述
同時在項目的啓動類上添加如下註解:
在這裏插入圖片描述

具體使用 @Cacheable

在想要進行的查詢上添加這個註解,在第一次請求數據時候,會請求到數據庫,然後加入緩存中,在下一次請求相同數據時候就會直接走緩存,不會再走數據庫查詢。
在這裏插入圖片描述

  @Override
  // value 表示我們開啓緩存的名字,key表示傳入的參數。
    @Cacheable(value = "student",key = "#id")
    public StudentEntity getById(Serializable id) {
        return super.getById(id);
    }

但是我們需要思考的問題是,我們如何知道前端頁面走到後端走的是數據庫查詢還是緩存查詢,就需要我們對MyBatis進行一個配置,讓查詢sql語句打印到控制檯。加上如下的配置信息。
在這裏插入圖片描述

測試

這個時候我們來進行一個測試,在第一次點擊前端的查詢以後
在這裏插入圖片描述
然後我們再度點擊前端的查詢頁面,後臺控制檯發現並沒有相同的查詢語句表示了並沒有走數據庫,我們再度打開redis客戶端進行查看(由於這裏我沒有安裝redis客戶端,截取老師圖片進行演示)發現找到了對於studen的數據,當然是二進制保存。
在這裏插入圖片描述

後言

對於二級緩存的應用還是十分廣泛的,若是大家想要進行測試,按照步驟來,自己定義對應的查詢頁面,加上註解和依賴,打開sql語句輸出到控制檯,就可以進行驗證。

刪除二級緩存數據

既然前面提交了可以在查詢時候將數據添加到二級緩存中,那麼要是數據被刪除了對於緩存中的數據是否也應該被刪除呢? 同樣的方法來實現以下:

 @CacheEvict(value = "student",key = "#id")
    @Override
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

二級緩存的註解(@Cacheable)寫在什麼位置

在前面提到了將註解寫在了Service層,於是就有思考爲什麼不寫在controller層或是Dao層呢?
如下我們看一張圖:
爲什麼不寫在Dao上呢?因爲對於一個sevice方法都知道可能會調用多個dao方法,然後將內容進行一個整理再放入到緩存中,在dao層就會顯得雜亂不堪。
在這裏插入圖片描述

業務層緩存

對於業務層的緩存我們可以列舉爲購物車數據,頭條新聞,秒殺商品的庫存,公告通知等,例如對於微博大V來說粉絲會有很多所以就會緩存最近的微博,防止粉絲在每一次的登錄時候都需要從數據庫中進行讀取,對數據庫的請求太大。還有就是對於四六級報名,也是先將報名信息緩存起來,等到凌晨時候再將數據讀寫到數據庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章