首页 大数据

Spring Boot整合Redis缓存:从入门到精通,解决性能瓶颈

分类:大数据
字数: (1688)
阅读: (9212)
内容摘要:Spring Boot整合Redis缓存:从入门到精通,解决性能瓶颈,

在如今高并发、大数据量的互联网应用中,缓存技术扮演着至关重要的角色。Spring Boot 提供了强大的缓存抽象,而 Redis 作为高性能的键值存储数据库,是 Spring Boot 整合缓存的首选方案。本文将深入探讨 Spring Boot 整合 Redis 缓存的各种细节,帮助你构建高效、稳定的应用程序。

1. 问题场景重现:没有缓存的痛

想象一个电商网站的商品详情页,每次用户访问都需要查询数据库,在高并发场景下,数据库的压力会急剧增加,导致响应时间变慢,甚至出现服务崩溃。例如,商品详情页每次访问都要查询商品信息、库存信息、评价信息等,这些数据在一段时间内通常是不变的。如果没有缓存,每次请求都会重复查询数据库,造成极大的资源浪费。

这种场景下,我们迫切需要引入缓存机制,将热点数据存储在缓存中,避免频繁访问数据库,提高系统的响应速度和吞吐量。类似场景还有:用户登录信息、配置信息、API 接口数据等。

Spring Boot整合Redis缓存:从入门到精通,解决性能瓶颈

2. Redis缓存原理深度剖析

Redis(Remote Dictionary Server)是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。Redis之所以能够实现高性能,与其自身的设计密不可分:

  • 内存存储:所有数据都存储在内存中,读写速度非常快。
  • 单线程架构:避免了多线程切换的开销,减少了锁的竞争。
  • 多路复用 I/O:使用 epoll 等 I/O 多路复用技术,能够同时处理多个客户端的请求。
  • 丰富的数据结构:支持字符串、哈希、列表、集合、有序集合等多种数据结构,满足不同的业务需求。

当 Spring Boot 整合 Redis 缓存后,数据流大致如下:

Spring Boot整合Redis缓存:从入门到精通,解决性能瓶颈
  1. 应用发起数据请求。
  2. Spring Boot 缓存管理器拦截请求,尝试从 Redis 缓存中获取数据。
  3. 如果缓存命中(cache hit),直接返回缓存数据。
  4. 如果缓存未命中(cache miss),则从数据库查询数据。
  5. 将查询到的数据存储到 Redis 缓存中,并返回给应用。

3. Spring Boot整合Redis缓存实战

3.1 添加依赖

首先,需要在 pom.xml 文件中添加 Redis 和 Spring Data Redis 的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>  <!-- Redis 连接池 -->
</dependency>

3.2 配置 Redis 连接信息

application.propertiesapplication.yml 文件中配置 Redis 连接信息:

Spring Boot整合Redis缓存:从入门到精通,解决性能瓶颈
spring:
  redis:
    host: localhost  # Redis 服务器地址
    port: 6379       # Redis 服务器端口
    password:        # Redis 服务器密码(可选)
    database: 0        # Redis 数据库索引(默认 0)
    timeout: 5000      # 连接超时时间,单位毫秒
    lettuce:
      pool:
        max-active: 8   # 最大连接数
        max-idle: 8     # 最大空闲连接数
        min-idle: 0     # 最小空闲连接数

3.3 开启缓存支持

在 Spring Boot 启动类上添加 @EnableCaching 注解,开启缓存支持:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching // 开启缓存支持
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

3.4 使用缓存注解

在需要缓存的方法上添加 @Cacheable@CacheEvict@CachePut 等注解:

Spring Boot整合Redis缓存:从入门到精通,解决性能瓶颈
  • @Cacheable:将方法的返回值缓存起来,下次调用相同参数的方法时,直接从缓存中获取。
  • @CacheEvict:从缓存中移除一个或多个 key。
  • @CachePut:更新缓存中的数据。

例如:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    @Cacheable(value = "product", key = "#id") // 将返回值缓存到名为 product 的缓存中,key 为 id
    public Product getProductById(Long id) {
        System.out.println("从数据库查询商品信息:" + id); // 模拟数据库查询
        // 实际业务逻辑是从数据库查询商品信息
        Product product = new Product();
        product.setId(id);
        product.setName("商品" + id);
        product.setPrice(99.99);
        return product;
    }

    @CacheEvict(value = "product", key = "#id") // 删除名为 product 的缓存中,key 为 id 的缓存数据
    public void deleteProductById(Long id) {
        System.out.println("删除商品:" + id);
        // 实际业务逻辑是从数据库删除商品信息
    }

}

3.5 自定义缓存管理器

默认情况下,Spring Boot 使用 SimpleCacheManager 作为缓存管理器。如果需要更高级的缓存管理功能,可以自定义缓存管理器。例如,配置缓存的过期时间:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.time.Duration;

@Configuration
public class RedisConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(60)) // 设置缓存过期时间为 60 秒
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); // 使用 JSON 序列化器
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

4. 实战避坑经验总结

  • 缓存穿透:大量请求查询不存在的 key,导致请求直接落到数据库。解决方案:
    • 缓存空对象:将不存在的 key 对应的空对象也缓存起来,设置较短的过期时间。
    • 使用布隆过滤器:在缓存之前使用布隆过滤器过滤掉不存在的 key。
  • 缓存击穿:某个热点 key 过期,大量请求同时访问该 key,导致请求直接落到数据库。解决方案:
    • 设置热点 key 永不过期。
    • 使用互斥锁:只允许一个请求访问数据库,其他请求等待,直到第一个请求将数据加载到缓存。
  • 缓存雪崩:大量 key 同时过期,导致大量请求直接落到数据库。解决方案:
    • 设置不同的过期时间,避免 key 同时过期。
    • 使用互斥锁:只允许少量请求访问数据库,其他请求等待。
    • 使用熔断器:当数据库压力过大时,熔断部分请求,避免数据库崩溃。

另外,在生产环境中,还需要考虑 Redis 的高可用方案,例如 Redis Sentinel 或 Redis Cluster,以保证缓存服务的稳定性和可靠性。可以使用宝塔面板快速部署 Redis,并配置合理的内存使用策略和持久化方案,例如 AOF 和 RDB 混合使用,来防止数据丢失。

5. 总结

通过本文的详细介绍,相信你已经掌握了 Spring Boot 整合 Redis 缓存 的方法和技巧。在实际项目中,可以根据具体的业务场景选择合适的缓存策略,并结合 Redis 的高可用方案,构建高性能、稳定的应用程序。合理利用缓存,可以极大地提升系统的性能,减少数据库的压力,提高用户体验。例如,对于秒杀系统,可以利用 Redis 的原子操作和高速缓存能力,应对高并发的请求,防止超卖等问题。 此外,结合 Nginx 的反向代理和负载均衡,可以进一步提升系统的整体性能和可用性,例如配置 upstream 实现多台 Redis 服务器的负载均衡。

Spring Boot整合Redis缓存:从入门到精通,解决性能瓶颈

转载请注明出处: 加班到秃头

本文的链接地址: http://m.acea2.store/article/32195.html

本文最后 发布于2026-04-06 08:27:24,已经过了21天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 云南过桥米线 5 天前
    请问一下,如果我的数据更新频率很高,缓存过期时间应该设置多长比较合适?
  • 佛系青年 6 小时前
    缓存击穿的解决方案讲的很清晰,学习了!之前只知道设置永不过期,没想到还可以用互斥锁。
  • 拖延症晚期 3 天前
    请问一下,如果我的数据更新频率很高,缓存过期时间应该设置多长比较合适?