Spring cache 和 Redis 的基礎知識

什么是緩存

緩存通俗點說就是臨時存儲數(shù)據(jù)的可高速訪問的地方。

當從原始位置獲取數(shù)據(jù)的代價太大或者時間太長的時候,就可以把獲取到的數(shù)據(jù)存放在緩存中,這樣下次訪問的時候就提高了訪問速度降低了訪問成本。

緩存的基本知識點
  1. 緩存的對象
    緩存的對象應該是花費了時間計算或者獲取到的數(shù)據(jù),并且這些數(shù)據(jù)在不久會被訪問到。
    在 Java 應用中,常見的緩存例子有如下幾種
  • Web Service 客戶端調用結果的緩存
  • 獲取到的 DB 數(shù)據(jù)
  • Servlet response 的緩存
  • 復雜計算的結果

代碼實例如 String 的 hashCode 計算結果

/** Cache the hash code for the string */
private int hash; // Default to 0
public int hashCode() {  
    //get from cache first  
    int h = hash;
    //cannot found    
    if (h == 0 && value.length > 0) { 
       char val[] = value; 
       for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        //set to cache
        hash = h;
    }
    return h;
}
  1. 緩存命中率
    緩存命中指的是當前請求發(fā)生在緩存中,就是說數(shù)據(jù)可以從緩存中獲得。

緩存命中率=緩存命中次數(shù)/總請求數(shù)[從緩存中讀取+慢速設備讀取]

緩存命中率是衡量緩存性能的一個重要指標。

  1. 緩存清除策略
    當緩存失效或者緩存空間不足的時候,需要提供緩存算法來清除一些不再使用的緩存數(shù)據(jù),這個時候就涉及到了緩存清除策略,一般稱做緩存算法。
    常見的緩存算法有:

等,具體介紹請參考維基百科或者查閱對應算法資料。

  1. 緩存存活期 TTL(Time To Live)
    存活期即從緩存中創(chuàng)建時間點開始直到它到期的一個時間段(不管在這個時間段內有沒有訪問都將過期)
  2. 緩存空閑期 TTI(Time To Idle)
    空閑期即一個數(shù)據(jù)多久沒被訪問將從緩存中移除的時間。

一般緩存使用方式

use cache

Spring cache abstraction

Spring cache 抽象層是 Spring 提供的一種能夠極小沖擊現(xiàn)有代碼的緩存機制。它提供的是不依賴具體緩存框架的,使用 AOP 方式實現(xiàn)的緩存機制。

Spring 的緩存技術還具備相當?shù)撵`活性,不僅能夠使用 SpEL(Spring Expression Language)來定義緩存的 key 和各種 condition,還提供開箱即用的緩存臨時存儲方案如 JDK 實現(xiàn)的緩存和 Guava cache,也支持和主流的專業(yè)緩存例如 EHCache 和 Redis 集成。

Spring 緩存技術基于 AOP 實現(xiàn), 因此有兩種實現(xiàn)模式 proxy 和 aspectj 可以選擇以適應不同情況。

Spring cache 的使用方式

Spring cache 提供了一些注解來聲明需要使用 Cache 的方法。

  • @Cacheable 聲明使用 Cache,方式是 put if not found
  • @CacheEvict 觸發(fā)緩存清除操作
  • @CachePut 在方法執(zhí)行的時候更新特定緩存,不影響方法執(zhí)行結果
  • @Caching 如果一個方法有多個緩存操作可以使用
  • @CacheConfig 配置當前類中使用的緩存配置

每一個注解的使用說明請看 Spring 的文檔。

使用 Spring Data Redis 實現(xiàn) Cache

Spring data redis 是 Spring 提供的對 Redis 操作進行封裝的框架,同時,他還提供了 Spring cache 的 Redis 實現(xiàn),因此我們可以使用他來完成 Redis 緩存的集成。

Redis

Redis是一個開源、支持網(wǎng)絡、基于內存、鍵值對存儲數(shù)據(jù)庫,可以用作數(shù)據(jù)庫、緩存和消息中間件。將 Redis 作為緩存的時候應該注意:

  • 設置最大可用的內存,使用 maxmemory 設置
  • 設置 Key 的清除策略(也就是緩存策略),使用 maxmemory-policy 設置

如果不設置最大可用內存的話:32位操作系統(tǒng),最大默認值為 3G,而64位則不限定。這樣就會導致內存占用過多,并且可能會對緩存特定 Key 的檢索速度有影響。

Redis 真正支持的緩存策略只有 LRU,但是我們可以在 redis.conf 中配置以下不同的參數(shù),來實現(xiàn)不同效果的 Key 清除策略:

  • noeviction:在客戶端操作會導致更多內存占用的時候拋出錯誤。
  • allkeys-lru: 優(yōu)先清除最近最少使用的 key 來為新加數(shù)據(jù)讓出空間。
  • volatile-lru: 優(yōu)先在設置了過期時間的 key 中清除最近最少使用的來為新加數(shù)據(jù)讓出空間。
  • allkeys-random: 隨機清除 key 來為新加數(shù)據(jù)讓出空間。
  • volatile-random: 隨機在設置了過期時間的 key 中清除一些
  • volatile-ttl: 在設置了過期時間的 Key 中根據(jù)存活期長短來清除,優(yōu)先清除存活期短的。

如果沒有 Key 滿足條件,volatile-lru、volatile-random 和 volatile-ttl 會和 noeviction 一樣的表現(xiàn)。

配置 Redis 作為 Spring cache 實現(xiàn)

簡單基于注解的配置如下:

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
    @Autowired
    private RedisPropertiesVO properties;
    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.afterPropertiesSet();
        factory.setHostName(properties.getHost());
        factory.setPort(properties.getPort());
        factory.setUsePool(true);
        factory.setDatabase(properties.getDatabase());
        return factory;
    }
    @Bean
    public RedisTemplate<Object, Object> redisTemplate() {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    public CacheManager cacheManager() {
        return new RedisCacheManager(redisTemplate());
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • 轉載地址:http://gnucto.blog.51cto.com/3391516/998509 Redis與Me...
    Ddaidai閱讀 21,466評論 0 82
  • 本文將從Redis的基本特性入手,通過講述Redis的數(shù)據(jù)結構和主要命令對Redis的基本能力進行直觀介紹。之后概...
    kelgon閱讀 61,264評論 23 625
  • 1.1 資料 ,最好的入門小冊子,可以先于一切文檔之前看,免費。 作者Antirez的博客,Antirez維護的R...
    JefferyLcm閱讀 17,110評論 1 51
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,953評論 6 342