Java配置Spring注解缓存

Spring注解缓存

  • 背景
  • 配置信息
    • 依赖引入
    • 配置RedisCacheConfig信息
    • 配置Redis连接信息
    • 关键性参数设置依据(阿里文档说明):
  • 注解的使用
    • 注解说明
    • @Cacheable注解的使用
    • @CacheEvict注解说明

背景

由于公司需要,最近准备使用Spring注解缓存来做Redis缓存,缓存一些配置信息,这里记录一下整个搭建过程,和使用上的心得。

配置信息

依赖引入

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.6.2</version>
</dependency>

配置RedisCacheConfig信息

这里采用Java配置,来配置Redis参数,这里有几个细节的地方,首先我加入了一个JdkOrRedis参数,来控制是用JDK缓存还是Redis缓存,其次是我将缓存key用了StringRedisSerializer序列化方式,这样当我们查看key的时候不会产生乱码的现象,最后是配置了全局的缓存过期时间。

@EnableCaching
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
     

    @Value("${redis.host}")
    private String host;
    @Value("${redis.port}")
    private int port;
    @Value("${redis.maxIdle}")
    private int maxIdle;
    @Value("${redis.maxActive}")
    private int maxActive;
    @Value("${redis.maxWait}")
    private long maxWait;
    @Value("${redis.JdkOrRedis}")
    private boolean JdkOrRedis;

    //缓存管理器bean
    @Bean
    public CacheManager cacheManager(RedisTemplate<String,String> redisTemplate){
     
        if(!JdkOrRedis){
     
            return new ConcurrentMapCacheManager();
        }
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        //这里可以设置一个默认的过期时间 单位是秒
        redisCacheManager.setDefaultExpiration(1800L);
        redisCacheManager.setUsePrefix(true);
        // 设置缓存的过期时间 单位是秒
//        Map expires = new HashMap<>();
//        expires.put("com.yuantu.biz.config.ConfigChainServiceImpl", 100L);
//        redisCacheManager.setExpires(expires);

        return redisCacheManager;
    }
    //连接工厂bean
    @Bean
    public RedisConnectionFactory redisConnectionFactory(){
     
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setHostName(host);
        jedisConnectionFactory.setPort(port);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWait);
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisConnectionFactory.setPoolConfig(jedisPoolConfig);
        jedisConnectionFactory.afterPropertiesSet();
        return jedisConnectionFactory;
    }
    @Bean
    //redisTemplate 的bean类
    public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory redisCF){
     
        RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisCF);
        redisTemplate.afterPropertiesSet();
        //将key用string序列号,避免出现乱码
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }

//    @Bean
//    public KeyGenerator keyGenerator() {
     
//        return new KeyGenerator() {
     
//            @Override
//            public Object generate(Object o, Method method, Object... params) {
     
//                StringBuilder sb = new StringBuilder();
//                sb.append(o.getClass().getName());
//                sb.append("-");
//                sb.append(method.getName());
//                sb.append("-");
//                for (Object param : params) {
     
//                    if(null != param){
     
//                        sb.append(param.toString());
//                    }
//                }
//                return sb.toString();
//            }
//        };
//    }
}

配置Redis连接信息

#访问地址
redis.host=47.114.38.76
#访问端口
redis.port=6379
#注意,如果没有password,此处不设置值,但这一项要保留
redis.password=
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
redis.maxIdle=20
#连接池的最大数据库连接数。设为0表示无限制
redis.maxActive=20
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWait=1000
#true:使用redis缓存,false:使用jvm本地缓存
redis.JdkOrRedis=true

关键性参数设置依据(阿里文档说明):

maxTotal(最大连接数)
想合理设置maxTotal(最大连接数)需要考虑的因素较多,如:
业务希望的Redis并发量;
客户端执行命令时间;
资源开销,例如虽然希望控制空闲连接,但又不希望因为连接池中频繁地释放和创建连接造成不必要的开销。
假设一次命令时间,即borrow|return resource加上Jedis执行命令 ( 含网络耗时)的平均耗时约为1ms,一个连接的QPS大约是1s/1ms = 1000,而业务期望的单个Redis的qps是50000(业务总的qps/Redis分片个数),那么理论上需要的资源池大小(即MaxTotal)是50000 / 1000 = 50。
但事实上这只是个理论值,除此之外还要预留一些资源,所以maxTotal可以比理论值大一些。这个值不是越大越好,一方面连接太多会占用客户端和服务端资源,另一方面对于Redis这种高QPS的服务器,如果出现大命令的阻塞,即使设置再大的资源池也无济于事。
maxIdle与minIdle
maxIdle实际上才是业务需要的最大连接数,maxTotal 是为了给出余量,所以 maxIdle 不要设置得过小,否则会有new Jedis(新连接)开销,而minIdle是为了控制空闲资源检测。连接池的最佳性能是maxTotal=maxIdle,这样就避免了连接池伸缩带来的性能干扰。如果您的业务存在突峰访问,建议设置这两个参数的值相等;如果并发量不大或者maxIdle设置过高,则会导致不必要的连接资源浪费。
您可以根据实际总QPS和调用Redis的客户端规模整体评估每个节点所使用的连接池大小。

注解的使用

注解说明

对于缓存声明,抽象提供了一组 Java 注解:

  • @Cacheable触发缓存填充

  • @CacheEvict触发逐出缓存

  • @CachePut更新缓存,而不会干扰方法的执行

  • @Caching重新组合要在一个方法上应用的多个缓存操作

  • @CacheConfig在类级别共享一些与缓存相关的常见设置

@Cacheable注解的使用

这个注解是用来读取缓存的,第一次读取的时候会走我们的逻辑,然后保存我们的结果,第二次进来的时候当发现key一样时,就直接返回缓存里面的值。value:缓存的名字,key:缓存的key,用的是SpringEL表达式,更多的用法可以自己去研究,一般这两个参数就够了。

    @Cacheable(value = "test",key = "#a + #b")
    public QueueDO test(String a, String b) {
     
        return dao.test(a, b);
    }

@CacheEvict注解说明

删除缓存

    @CacheEvict(value = "test",key = "#a + #b")
    public void test(String a, String b){
     

    }

你可能感兴趣的:(redis系列,redis,java,spring,缓存)