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-active 和 max-idle,避免频繁创建连接。
    • 监控连接池指标(如 active、idle)防止资源耗尽。
  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 可以实现高性能、高可用的缓存与分布式服务。

相关推荐
小小龙学IT41 分钟前
C++ Redis 客户端深度解析(hiredis 与 redis-plus-plus)——工业数采实时缓存 C++ 侧实战
c++·redis·缓存
mengge.cloud1 小时前
Redis
运维·服务器·数据库·redis·缓存·云计算
欣栀♡1 小时前
Redis 缓存穿透、击穿、雪崩,背出定义只是及格线
数据库·redis·缓存
codigger1 小时前
Redis 正式接入 AI:当"最懂速度的数据库"开始解决"记忆问题"
redis·分布式·后端·ai·向量检索
禾小西1 小时前
08丨Redis 哨兵集群:哨兵故障后还能完成切换吗?
数据库·redis·缓存
挖掘狂人2 小时前
Redis 正式接入 AI:当"最懂速度的数据库"开始解决"记忆问题"
人工智能·redis·后端
省钱兄--zs2 小时前
24小时自助健身房系统软件开发实战:从架构设计到部署全指南
java·数据仓库·spring boot·系统架构·需求分析
IT研究室2 小时前
最新计算机毕业设计选题推荐-基于spring boot的智慧教学资源管理与互动交流平台-网站-文档指导-Java-springboot
java·spring boot·课程设计
程序猿_极客2 小时前
【免费】分享一套优质的基于Java的智慧养老院管理系统的设计与实现(带可视化),源码+文档+视频详解(讲解)
java·spring boot·后端·养老院管理系统
程序猿_极客2 小时前
【免费】分享一套优质的基于SpringBoot的旅游管理系统的设计与实现(带智能推荐算法功能),源码+文档+视频详解(讲解)
java·spring boot·课程设计·旅游管理系统·计算机专业项目