Spring Boot集成cache

緩存簡介

工作機制是:先從緩存中讀取數據,如果沒有再從慢速設備上讀取實際數據(數據也會存入緩存);緩存什麼:那些經常讀取且不經常修改的數據/那些昂貴(CPU/IO)的且對於相同的請求有相同的計算結果的數據。例如Maven/京東物流都是這種思想

緩存命中率

即從緩存中讀取數據的次數 與 總讀取次數的比率,命中率越高越好:

命中率 = 從緩存中讀取次數 / (總讀取次數[從緩存中讀取次數 + 從慢速設備上讀取的次數])

緩存策略

Eviction policy 移除策略,即如果緩存滿了,從緩存中移除數據的策略;常見的有LFU、LRU、FIFO:

FIFO(First In First Out):先進先出算法,即先放入緩存的先被移除;

LRU(Least Recently Used):最久未使用算法,使用時間距離現在最久的那個被移除;

LFU(Least Frequently Used):最近最少使用算法,一定時間段內使用次數(頻率)最少的那個被移除;

TTL(Time To Live )存活期,即從緩存中創建時間點開始直到它到期的一個時間段(不管在這個時間段內有沒有訪問都將過期)

TTI(Time To Idle)空閒期,即一個數據多久沒被訪問將從緩存中移除的時間。

spring定義了org.springframework.cache.CacheManager和org.springframework.cache.Cache接口來統一不同的緩存技術,而SpringBoot爲我們提供了自動配置多個CacheManager的實現

EhCacheCacheConfiguration.class EhCache實現緩存

GuavaCacheConfiguration.class Guava實現緩存

JCacheCacheConfiguration.class JCache實現緩存

GenericCacheConfiguration.class Collection實現緩存

SimpleCacheConfiguration.class ConcurrentMap實現緩存

在不做任何額外配置的情況下,默認使用SimpleCacheConfiguration,即ConcurrentMapCacheManager。Springboot支持以“spring.cache”爲前綴的屬性來配置,如:

spring.cache.type=#ehcache,generic,redis,jcache等

spring.cache.cache-names=#緩存名稱

spring.cache.ehcache.config= #ehcache配置文件地址

在Spring Boot中通過@EnableCaching註解自動化配置合適的緩存管理器(CacheManager),Spring Boot根據下面的順序去偵測緩存提供者:

Generic

JCache (JSR-107)

EhCache 2.x

Hazelcast

Infinispan

Redis

Guava

Simple

除了按順序偵測外,我們也可以通過配置屬性spring.cache.type來強制指定。我們可以通過debug調試查看cacheManager對象的實例來判斷當前使用了什麼緩存。

默認的ConcurrentMapCacheManager使用步驟:

1. 引入pom.xml

org.springframework.boot

spring-boot-starter-cache

2. 在主類或configuration類中通過 @EnableCaching 開啓緩存

3. @Cacheable 查詢,首先檢查緩存是否存在,如果有則直接從緩存取然後返回,若沒有則查DB,並將結果(有值或空)添加數據到緩存中。緩存名稱爲people,緩存key爲person的id屬性

參數:

value、cacheNames:兩個等同的參數(cacheNames爲Spring 4新增,作爲value的別名),用於指定緩存存儲的集合名。由於Spring 4中新增了@CacheConfig,因此在Spring 3中原本必須有的value屬性,也成爲非必需項了

key:緩存對象存儲在Map集合中的key值,非必需,缺省按照函數的所有參數組合作爲key值,若自己配置需使用SpEL表達式,比如:@Cacheable(key = "#p0"):使用函數第一個參數作爲緩存的key值,更多關於SpEL表達式的詳細內容可參考官方文檔

condition:緩存對象的條件,非必需,也需使用SpEL表達式,只有滿足表達式條件的內容纔會被緩存,默認緩存所有結果數據。比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有當第一個參數的長度小於3的時候纔會被緩存,若做此配置上面的AAA用戶就不會被緩存。

4. @CachePut 插入或更新到DB後,檢查緩存中是否有該key,有則更新,沒有則新增。新增或更新的內容爲接口的返回值,所以保存/更新接口必須有返回值。 若返回值爲空,則緩存也會爲空值。

參數:同上

5. @CacheEvict 表示從緩存people中刪除key爲id的數據

參數:除上述之外,還有2個。

allEntries:非必需,默認爲false。當爲true時,會移除所有數據

beforeInvocation:非必需,默認爲false,會在調用方法之後移除數據。當爲true時,會在調用方法之前移除數據。

ehcache使用步驟:

1. pom.xml引入依賴:

net.sf.ehcache

ehcache

2.8.3

2. 在src/main/resources目錄下創建:ehcache.xml

xsi:noNamespaceSchemaLocation="ehcache.xsd">

maxEntriesLocalHeap="200"

timeToLiveSeconds="600">

或配置

spring.cache.type=ehcache

spring.cache.ehcache.config=classpath:config/another-config.xml

redis使用步驟:

1. pom.xml引入依賴:

org.springframework.boot

spring-boot-starter-redis

2. properties中配置redis端口等

3. 配置RedisCacheManager,RedisTemplate的bean,具體參考源碼

綜合說明:

1. spring cache是spring3.1就有的概念,通過AOP實現,提供註解方式,但由於是進程內的緩存,適合於單機,分佈式環境下不適用。EhCache提供了集羣環境下的緩存同步策略,但是同步依然需要一定的時間,短暫的緩存不一致依然存在。在一些要求高一致性(任何數據變化都能及時的被查詢到)的系統和應用中,就不能再使用EhCache來解決了,這個時候使用集中式緩存是個不錯的選擇

2. redis是集中式緩存,通過上述註解方式使用redisCacheManager,則緩存數據存儲在redis,保證分佈式環境數據一致性。

實例源碼: test1-cache

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