当前位置: 首页 > news >正文

Spring Boot 集成 Redis 实战总结

Spring Boot 集成 Redis 实战总结

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

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

    spring:redis:host: localhostport: 6379password: 123456database: 0lettuce:pool:max-active: 16   # 最大连接数max-idle: 8      # 最大空闲连接min-idle: 2      # 最小空闲连接
    
  3. 序列化配置
    默认的 RedisTemplate 使用 JDK 序列化(可读性差),推荐自定义序列化:

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

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

    @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. 发布订阅

    // 发布端
    redisTemplate.convertAndSend("channel", "message");// 订阅端
    @Component
    public class RedisMessageListener implements MessageListener {@Overridepublic void onMessage(Message message, byte[] pattern) {System.out.println("收到消息: " + new String(message.getBody()));}
    }
    
  3. 分布式锁
    使用 Redisson 或手动实现:

    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 简化缓存逻辑:

    @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 批量操作
    减少网络开销:

    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 脚本
    实现原子性操作(如限流):

    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. 过期时间随机化
    防止缓存雪崩:

    int expireTime = 3600 + new Random().nextInt(600); // 3600~4200秒
    redisTemplate.expire("key", expireTime, TimeUnit.SECONDS);
    
  5. 异步删除
    对于大 Key 删除,使用 UNLINK 替代 DEL

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

http://www.xdnf.cn/news/62083.html

相关文章:

  • Idea中实用设置和插件
  • 系统架构师2025年论文《论基于UML的需求分析》
  • 项目实战 -- 发布管理
  • 把dll模块注入到游戏进程的方法_基于文件修改的注入方式
  • SQL语言的三大分类及其应用详解
  • 欧拉-国产操作系统替代产品如何
  • FreeRTOS中的优先级翻转问题及其解决方案:互斥信号量详解
  • ESP-ADF外设子系统深度解析:esp_peripherals组件架构与核心设计(显示输出类外设之IS31FL3216)
  • DeepSeek+Cursor+Devbox+Sealos项目实战
  • IP精准检测“ipinfo”
  • Flask API 项目 Swagger 版本打架不兼容
  • ADC数据不稳定的解决方案
  • Java学习手册:HTTP 协议基础知识
  • 【Maven基础】
  • 霍尔效应的应用领域
  • QT 5.15 程序打包
  • 【无人机】无人机方向的设置,PX4飞控方向,QGC中设置飞控的方向/旋转角度。PX4使用手册飞行控制器/传感器方向
  • [原理分析]安卓15系统大升级:Doze打盹模式提速50%,续航大幅增强,省电提升率5%
  • Android Studio 国内镜像使用与 SDK 下载速度优化指南
  • list的学习
  • 超详细mac上用nvm安装node环境,配置npm
  • 基于RK3588+FPGA+AI YOLO全国产化的无人船目标检测系统(二)平台设计
  • Java 性能优化:如何利用 APM 工具提升系统性能?
  • 每日一题(小白)回溯篇7
  • python测试框架之pytest
  • 基于STC89C52RC和8X8点阵屏、独立按键的匹配消除类小游戏
  • 线上救急-AWS限频
  • SQL Server基础
  • 在ARM Linux应用层下驱动MFRC522
  • spark和hadoop区别联系