Spring Boot 集成 Redis 实战总结

Spring Boot 集成 Redis 实战总结

一、基础集成与配置
  1. 依赖引入

    xml 复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    • 默认使用 Lettuce 作为连接池(优于 Jedis,支持异步和 Reactive 编程)。
  2. 配置文件

    yaml 复制代码
    spring:
      redis:
        host: localhost
        port: 6379
        password: 123456
        database: 0
        lettuce:
          pool:
            max-active: 16   # 最大连接数
            max-idle: 8      # 最大空闲连接
            min-idle: 2      # 最小空闲连接
  3. 序列化配置

    默认的 RedisTemplate 使用 JDK 序列化(可读性差),推荐自定义序列化:

    java 复制代码
    @Configuration
    public class RedisConfig {
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(factory);
            // 使用 Jackson2JsonRedisSerializer
            template.setDefaultSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
            template.setKeySerializer(RedisSerializer.string());
            template.setHashKeySerializer(RedisSerializer.string());
            return template;
        }
    }

二、实战使用场景
  1. 基础操作(字符串、哈希、列表)

    java 复制代码
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // 字符串
    redisTemplate.opsForValue().set("key", "value", 60, TimeUnit.SECONDS);
    Object value = redisTemplate.opsForValue().get("key");
    
    // 哈希
    redisTemplate.opsForHash().put("user:1", "name", "John");
    String name = (String) redisTemplate.opsForHash().get("user:1", "name");
    
    // 列表
    redisTemplate.opsForList().leftPush("tasks", "task1");
    List<Object> tasks = redisTemplate.opsForList().range("tasks", 0, -1);
  2. 发布订阅

    java 复制代码
    // 发布端
    redisTemplate.convertAndSend("channel", "message");
    
    // 订阅端
    @Component
    public class RedisMessageListener implements MessageListener {
        @Override
        public void onMessage(Message message, byte[] pattern) {
            System.out.println("收到消息: " + new String(message.getBody()));
        }
    }
  3. 分布式锁

    使用 Redisson 或手动实现:

    java 复制代码
    public boolean tryLock(String key, String value, long expireTime) {
        return Boolean.TRUE.equals(
            redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.SECONDS)
        );
    }
    
    public void unlock(String key) {
        redisTemplate.delete(key);
    }

三、常用技巧
  1. 缓存注解

    使用 @Cacheable@CacheEvict 简化缓存逻辑:

    java 复制代码
    @Cacheable(value = "users", key = "#userId", unless = "#result == null")
    public User getUserById(Long userId) {
        // 查询数据库
    }
    
    @CacheEvict(value = "users", key = "#userId")
    public void updateUser(User user) {
        // 更新数据库
    }
  2. Pipeline 批量操作

    减少网络开销:

    java 复制代码
    List<Object> results = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
        for (int i = 0; i < 100; i++) {
            connection.stringCommands().set(("key" + i).getBytes(), ("value" + i).getBytes());
        }
        return null;
    });
  3. Lua 脚本

    实现原子性操作(如限流):

    java 复制代码
    String script = "local count = redis.call('incr', KEYS[1]) " +
                    "if count == 1 then redis.call('expire', KEYS[1], ARGV[1]) end " +
                    "return count";
    RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
    Long count = redisTemplate.execute(redisScript, Collections.singletonList("rate_limit:api1"), 60);

四、性能优化
  1. 连接池调优

    • 根据并发量调整 max-activemax-idle,避免频繁创建连接。
    • 监控连接池指标(如 activeidle)防止资源耗尽。
  2. 避免大 Key 和热 Key

    • 大 Key:拆分数据(如哈希拆分为多个字段)。
    • 热 Key:本地缓存 + 随机过期时间,或使用 Redis Cluster 分散压力。
  3. 合理选择数据结构

    • 统计 UV:HyperLogLog(省内存)。
    • 排行榜:ZSet。
    • 短链接映射:String。
  4. 过期时间随机化

    防止缓存雪崩:

    java 复制代码
    int expireTime = 3600 + new Random().nextInt(600); // 3600~4200秒
    redisTemplate.expire("key", expireTime, TimeUnit.SECONDS);
  5. 异步删除

    对于大 Key 删除,使用 UNLINK 替代 DEL

    java 复制代码
    redisTemplate.unlink("largeKey");
  6. 监控与日志

    • 开启 Redis 慢查询日志:slowlog-log-slower-than 10000(单位:微秒)。
    • 使用 Prometheus + Grafana 监控 Redis 性能指标(QPS、内存、命中率)。

五、常见问题
  1. 缓存穿透
    • 方案:空值缓存 + 布隆过滤器。
  2. 缓存击穿
    • 方案:互斥锁(如 Redis SETNX)。
  3. 数据一致性
    • 方案:延迟双删、订阅 Binlog 异步更新。

六、高级扩展
  • Redisson:实现分布式锁、限流器、延迟队列。
  • Spring Cache Reactive:响应式编程支持。
  • Redis Cluster :集群模式下注意 hash tag 分片优化。

通过合理配置和优化,Spring Boot 集成 Redis 可以实现高性能、高可用的缓存与分布式服务。

相关推荐
慌糖1 小时前
Spring Boot音乐服务器项目-查询喜欢的音乐模块
服务器·spring boot·mybatis
尚学教辅学习资料4 小时前
SpringBoot3.x入门到精通系列:1.2 开发环境搭建
spring boot·gradle·maven·intellij idea·jdk17·开发环境
运维小杨4 小时前
Redis主从复制搭建
数据库·redis·缓存
找不到、了4 小时前
Kafka在Springboot项目中的实践
spring boot·分布式·kafka
用户053140608816 小时前
Spring Boot AOP 切点表达式深度解析
spring boot
李长渊哦6 小时前
SpringBoot中ResponseEntity的使用详解
java·spring boot·后端
用户053140608816 小时前
Spring Boot AOP详解:优雅解耦,提升代码可维护性
spring boot
weixin_491853316 小时前
Spring Boot 中整合WebSocket
spring boot·后端·websocket
喵手6 小时前
Spring Boot 异常处理:从全局捕获到优化用户体验!
spring boot·python·ux
不会理财的程序员不是好老板6 小时前
Java Spring Boot项目中集成Swagger完整步骤
java·开发语言·spring boot