spring cache - redis

概述

官网:https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache
描述:‎

  • 从版本 3.1 开始,Spring 框架支持向 Spring 应用程序添加缓存。与‎‎事务‎‎支持类似,缓存抽象允许一致地使用各种缓存解决方案,同时对代码的影响最小。‎

  • ‎在Spring Framework 4.1中,缓存抽象得到了显着扩展,支持‎‎JSR-107注释‎‎和更多自定义选项。‎

配置

引入依赖

  • cache:
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
  • 引入redis
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

配yaml,type是redis

spring:
  cache:
    type: redis
    redis:
      # 单位是毫秒
      time-to-live: 3600000
      # 缓存null值,可防止缓存穿透
      cache-null-values: true
      #key-prefix: CACHE_ # 设置缓存前缀,如果不设置,则用缓存名字作为前缀
      # 是否使用前缀,如果不用前缀,键只有key值
      use-key-prefix: true

主启动类标@EnableCaching 开启缓存

常用注解

@Cacheable

含义:

  • 当前方法需要缓,如果缓存中有,方法不调用
  • 如果缓存中没有,会调用方法,并把结果放入缓存中

默认行为:

  • 如果缓存中有,方法不调用
  • key默认自动生成:缓存名字(必须指定)::SimpleKey
  • 默认使用jdk序列化机制,将数据存到redis
  • 默认ttl-1

自定义:

  • 指定生成的缓存使用的key:使用属性key指定,key接收一个SpEL表达式(下文有SpEL),如果要自定义字符串,需要写在单引号里面,例如:key = "'myKey'"
  • 指定缓存存活时间:在配置文件中配置:spring.cache.redis.time-to-live(以毫秒为单位)
  • 将数据保存为json格式:org.springframework.data.redis.cache.RedisCacheConfiguration
    import org.springframework.boot.autoconfigure.cache.CacheProperties;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    
    /**
     * @program: gulimall
     * @description: 缓存配置类
     * @author: liangjiayy
     * @create: 2022-05-22 11:40
     **/
    @Configuration
    @EnableCaching
    public class MyCacheConfig {
        @Bean
        RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
            CacheProperties.Redis redisProperties = cacheProperties.getRedis();
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
    
            //用json序列化,注意serializeValuesWith并没有设置值,只是返回一个新的对象
            config = config.serializeValuesWith(
                    RedisSerializationContext.SerializationPair.fromSerializer(
                            new GenericJackson2JsonRedisSerializer()));
            if (redisProperties.getTimeToLive() != null) {
                config = config.entryTtl(redisProperties.getTimeToLive());
            }
    
            if (redisProperties.getKeyPrefix() != null) {
                config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
            }
    
            if (!redisProperties.isCacheNullValues()) {
                config = config.disableCachingNullValues();
            }
    
            if (!redisProperties.isUseKeyPrefix()) {
                config = config.disableKeyPrefix();
            }
    
            return config;
        }
    }
    

配置原理见源码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SpEL:

Table 9. Cache SpEL available metadata
NameLocationDescriptionExample

methodName

Root object

The name of the method being invoked

#root.methodName

method

Root object

The method being invoked

#root.method.name

target

Root object

The target object being invoked

#root.target

targetClass

Root object

The class of the target being invoked

#root.targetClass

args

Root object

The arguments (as array) used for invoking the target

#root.args[0]

caches

Root object

Collection of caches against which the current method is run

#root.caches[0].name

Argument name

Evaluation context

Name of any of the method arguments. If the names are not available (perhaps due to having no debug information), the argument names are also available under the where stands for the argument index (starting from ).#a<#arg>#arg0

#iban or (you can also use or notation as an alias).#a0#p0#p<#arg>

result

Evaluation context

The result of the method call (the value to be cached). Only available in expressions, expressions (to compute the ), or expressions (when is ). For supported wrappers (such as ), refers to the actual object, not the wrapper.unlesscache putkeycache evictbeforeInvocationfalseOptional#result

#result

@CacheEvict

失效模式,当更新数据库的时候把对应缓存也删了。

一次性删多个缓存?

  • 使用@Caching,指定多个值
    在这里插入图片描述
  • 使用@CacheEvict(value = "category",allEntries = true)(推荐)
    把所有在category分区的数据都删了

@CachePut(略)

双写模式,写入数据库的同时,写入缓存中

不足:

读模式可能出现的问题及解决:

  • 缓存穿透(查询null值,总是查数据库):Spring Cache已解决!配置缓存空值即可
    在这里插入图片描述

  • 缓存击穿(大并发查询正好过期的数据):设置注解属性sync=true
    在这里插入图片描述

  • 缓存雪崩(大量key同时过期):加随机时间。设置过期时间,不是同时缓存的,不会同时过期!
    在这里插入图片描述

写模式可能出现的问题及解决:

  • 读多写少:加读写锁
  • 引入canal,感知mysql更新去更新数据库
  • 读多写多:直接查数据库

总结:

  • 常规数据(读多写少,即时性、一致性要求不高的数据),完全可以用spring cache;写模式,只要缓存的数据有过期时间就足够了
  • 特殊数据:特殊设计
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值