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 可以实现高性能、高可用的缓存与分布式服务。

相关推荐
JH30739 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
qq_124987075312 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_12 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
2301_8187320612 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea
此生只爱蛋12 小时前
【Redis】主从复制
数据库·redis
汤姆yu15 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
暮色妖娆丶15 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
biyezuopinvip17 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现
惊讶的猫17 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
JavaGuide17 小时前
一款悄然崛起的国产规则引擎,让业务编排效率提升 10 倍!
java·spring boot