Spring Boot 缓存 与 Redis

发布于:2025-07-17 ⋅ 阅读:(30) ⋅ 点赞:(0)

缓存是提升接口响应速度和降低数据库压力的重要手段。

Redis

通过Socket访问到缓存服务,效率比EnCache低,对集群和分布式支持友好。

EnCache

纯Java的进程缓存,直接在JVM中进行缓存,速度快、效率高,但对分布式集群的支持不太好。

ConcurrentHashMap

Manager

Spring Boot 默认提供的缓存管理器,线程安全,官方明确不建议在生产环境使用。

表 Java缓存方案对比

1 缓存注解

Spring Boot 提供了缓存抽象层,并结合JSR-107标准,提供了多个缓存注解。

@Cacheable

查询缓存。

@CachePut

更新缓存。

@CacheEvict

删除缓存。

表 常用的缓存注解

这些注解作用于方法级别,在不侵入业务逻辑的前提下,实现缓存管理。它们是基于AOP实现的,有以下注意项:

  1. 只能用于public方法上。
  2. 只有当调用方通过Spring代理调用该方法时才生效。(同一个类中直接调用不生效)
  3. 需要启用缓存功能。@EnableCaching。

1.1 缓存key 生成策略

缓存注解keyGenerator字段用于指定该方法缓存key的生成策略。

图 key 生成策略需实现的接口

    @Bean
    public KeyGenerator paramsKeyGenerator() {
        return ((target, method, params) -> {
           StringBuilder sb = new StringBuilder();
           sb.append(target.getClass().getSimpleName());
           sb.append("::");
           sb.append(method.getName());
           for (Object obj : params) {
               sb.append("::");
               sb.append(obj.toString());
           }
           return sb.toString();
        });
    }

2 Redis 缓存策略

maven依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

缓存策略配置:

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30))
                .disableCachingNullValues() // 避免缓存穿透
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }

}

2.1 redis 连接池

Spring Boot 2.x 默认使用Lettuce作为Redis客户端。

Lettuce

基于Netty的异步非阻塞通信;原生线程安全;长连接Lettuce性能优势更明显;CPU利用率更高效。

Jedis

同步阻塞通信;非线程安全;

表 Lettuce 与 Jedis对比

2.3 Redis 缓存问题

1 缓存穿透:查询一个根本不存在的数据,导致每次查询都会访问数据库。

使用布隆过滤器(检索元素是否存在集合中)。它内存占用小。判断元素存在有误差,但是判断元素不存在绝对准确。

2 缓存击穿:某个热点key突然实现,大量请求同时访问时,会击穿缓存直接访问数据库。

使用互斥锁或逻辑过期。也可以设置热点key永不过期或是后台刷新热点key缓存。

3 缓存雪崩:大量缓存key同时失效,大量请求直接访问数据库。发生场景有:1)缓存服务器重启;2)大量缓存设置相同过期时间。

缓存key的过期时间随机化。


网站公告

今日签到

点亮在社区的每一天
去签到