Spring Boot整合Redis实现缓存 - 详细教程与实战

12.8k 阅读
42 评论
256 收藏
85 点赞

在现代Web应用中,缓存是提高系统性能的重要手段之一。Redis作为高性能的键值对存储数据库,常被用于缓存解决方案。本文将详细介绍如何在Spring Boot项目中整合Redis实现缓存功能。

一、Redis简介

Redis(Remote Dictionary Server)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

Redis优势:

  • 性能极高 - Redis能支持超过10万次/秒的读写频率
  • 丰富的数据类型 - 支持Strings, Lists, Sets, Sorted Sets, Hashes等
  • 原子性 - 所有操作都是原子性的
  • 丰富的特性 - 支持发布/订阅, 通知, key过期等特性

二、Spring Boot集成Redis

1. 添加依赖

在pom.xml中添加Spring Data Redis和Lettuce依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.1.5.RELEASE</version>
</dependency>

2. 配置Redis连接

在application.yml中配置Redis连接信息:

spring:
  redis:
    host: localhost
    port: 6379
    password: 
    database: 0
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: -1ms

3. 配置缓存管理器

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofMinutes(10)))
                .build();
    }
}

4. 使用缓存注解

在Service层方法上使用缓存注解:

@Service
public class UserService {

    @Cacheable(value = "userCache", key = "#id")
    public User getUserById(Long id) {
        // 模拟数据库查询
        return userRepository.findById(id).orElse(null);
    }
    
    @CachePut(value = "userCache", key = "#user.id")
    public User updateUser(User user) {
        // 更新用户
        return userRepository.save(user);
    }
    
    @CacheEvict(value = "userCache", key = "#id")
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

三、缓存实战案例

以下是一个商品信息缓存的完整示例:

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductService productService;
    
    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return productService.getProductById(id);
    }
    
    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        return productService.createProduct(product);
    }
    
    @PutMapping("/{id}")
    public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
        return productService.updateProduct(id, product);
    }
    
    @DeleteMapping("/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.deleteProduct(id);
    }
}

注意: 在实际项目中,应根据业务需求合理设置缓存过期时间,避免缓存雪崩和缓存穿透问题。可以使用@Cacheable的condition和unless属性进行条件缓存。

四、缓存常见问题与解决方案

1. 缓存穿透

问题:大量查询不存在的数据,绕过缓存直接查询数据库

解决方案:

  • 对空结果进行缓存,设置较短的过期时间
  • 使用布隆过滤器

2. 缓存雪崩

问题:大量缓存同时失效,导致请求直接打到数据库

解决方案:

  • 设置不同的过期时间
  • 使用缓存集群提高可用性
  • 限流降级

3. 缓存击穿

问题:热点key失效瞬间,大量请求直接访问数据库

解决方案:

  • 设置热点数据永不过期
  • 使用互斥锁

五、总结

Spring Boot整合Redis实现缓存可以显著提升系统性能,减少数据库压力。通过本文的学习,你应该掌握了:

  1. Redis的基本概念和优势
  2. Spring Boot集成Redis的步骤
  3. 使用缓存注解实现CRUD操作的缓存
  4. 缓存常见问题及解决方案

在实际项目中,应根据业务场景合理使用缓存,并注意缓存的一致性问题。