Spring cache 和 Redis 的基础知识

什么是缓存

缓存通俗点说就是临时存储数据的可高速访问的地方。

当从原始位置获取数据的代价太大或者时间太长的时候,就可以把获取到的数据存放在缓存中,这样下次访问的时候就提高了访问速度降低了访问成本。

缓存的基本知识点
  1. 缓存的对象
    缓存的对象应该是花费了时间计算或者获取到的数据,并且这些数据在不久会被访问到。
    在 Java 应用中,常见的缓存例子有如下几种
  • Web Service 客户端调用结果的缓存
  • 获取到的 DB 数据
  • 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. 缓存命中率
    缓存命中指的是当前请求发生在缓存中,就是说数据可以从缓存中获得。

缓存命中率=缓存命中次数/总请求数[从缓存中读取+慢速设备读取]

缓存命中率是衡量缓存性能的一个重要指标。

  1. 缓存清除策略
    当缓存失效或者缓存空间不足的时候,需要提供缓存算法来清除一些不再使用的缓存数据,这个时候就涉及到了缓存清除策略,一般称做缓存算法。
    常见的缓存算法有:
  • Least Recently Used (LRU)
  • Most Recently Used (MRU)
  • Least-Frequently Used(LFU)
  • Low Inter-reference Recency Set (LIRS)

等,具体介绍请参考维基百科或者查阅对应算法资料。

  1. 缓存存活期 TTL(Time To Live)
    存活期即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期)
  2. 缓存空闲期 TTI(Time To Idle)
    空闲期即一个数据多久没被访问将从缓存中移除的时间。

一般缓存使用方式

Spring cache 和 Redis 的基础知识_第1张图片
use cache

Spring cache abstraction

Spring cache 抽象层是 Spring 提供的一种能够极小冲击现有代码的缓存机制。它提供的是不依赖具体缓存框架的,使用 AOP 方式实现的缓存机制。

Spring 的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的 key 和各种 condition,还提供开箱即用的缓存临时存储方案如 JDK 实现的缓存和 Guava cache,也支持和主流的专业缓存例如 EHCache 和 Redis 集成。

Spring 缓存技术基于 AOP 实现, 因此有两种实现模式 proxy 和 aspectj 可以选择以适应不同情况。

Spring cache 的使用方式

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

  • @Cacheable 声明使用 Cache,方式是 put if not found
  • @CacheEvict 触发缓存清除操作
  • @CachePut 在方法执行的时候更新特定缓存,不影响方法执行结果
  • @Caching 如果一个方法有多个缓存操作可以使用
  • @CacheConfig 配置当前类中使用的缓存配置

每一个注解的使用说明请看 Spring 的文档。

使用 Spring Data Redis 实现 Cache

Spring data redis 是 Spring 提供的对 Redis 操作进行封装的框架,同时,他还提供了 Spring cache 的 Redis 实现,因此我们可以使用他来完成 Redis 缓存的集成。

Redis

Redis是一个开源、支持网络、基于内存、键值对存储数据库,可以用作数据库、缓存和消息中间件。将 Redis 作为缓存的时候应该注意:

  • 设置最大可用的内存,使用 maxmemory 设置
  • 设置 Key 的清除策略(也就是缓存策略),使用 maxmemory-policy 设置

如果不设置最大可用内存的话:32位操作系统,最大默认值为 3G,而64位则不限定。这样就会导致内存占用过多,并且可能会对缓存特定 Key 的检索速度有影响。

Redis 真正支持的缓存策略只有 LRU,但是我们可以在 redis.conf 中配置以下不同的参数,来实现不同效果的 Key 清除策略:

  • noeviction:在客户端操作会导致更多内存占用的时候抛出错误。
  • allkeys-lru: 优先清除最近最少使用的 key 来为新加数据让出空间。
  • volatile-lru: 优先在设置了过期时间的 key 中清除最近最少使用的来为新加数据让出空间。
  • allkeys-random: 随机清除 key 来为新加数据让出空间。
  • volatile-random: 随机在设置了过期时间的 key 中清除一些
  • volatile-ttl: 在设置了过期时间的 Key 中根据存活期长短来清除,优先清除存活期短的。

如果没有 Key 满足条件,volatile-lru、volatile-random 和 volatile-ttl 会和 noeviction 一样的表现。

配置 Redis 作为 Spring cache 实现

简单基于注解的配置如下:

@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 redisTemplate() {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    public CacheManager cacheManager() {
        return new RedisCacheManager(redisTemplate());
    }
}

你可能感兴趣的:(Spring cache 和 Redis 的基础知识)