使用 Redis 实现接口缓存:提升性能的完整指南

ops/2025/3/19 4:42:25/

1. 为什么需要接口缓存

接口缓存的主要目的是减少重复计算和数据库查询,从而提升性能。常见场景包括:
高并发请求缓存热门数据,避免频繁访问数据库
复杂计算缓存计算结果,减少 CPU 压力。
外部 API 调用缓存外部 API 的响应,降低延迟。


2. Redis 简介

Redis 是一个开源的、基于内存的键值存储系统,支持多种数据结构(如字符串、哈希、列表、集合等)。它的主要优势包括:
高性能:数据存储在内存中,读写速度极快。
持久化:支持将数据持久化到磁盘,防止数据丢失。
丰富的数据结构:支持字符串、哈希、列表、集合等。


3. 实现接口缓存的步骤

以下是一个完整的实现接口缓存的步骤,以 Java 和 Spring Boot 为例。

3.1 添加依赖

pom.xml 中添加 Redis 和 Spring Boot 相关依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.2 配置 Redis

application.properties 中配置 Redis 连接信息:

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.timeout=2000
3.3 创建 Redis 配置类

配置 RedisTemplate,用于操作 Redis:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new StringRedisSerializer());return template;}
}
3.4 实现缓存逻辑

在 Service 层实现缓存逻辑:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;@Service
public class UserService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final String CACHE_KEY = "user_";public String getUserInfo(String userId) {// 从缓存中获取数据String cacheKey = CACHE_KEY + userId;String userInfo = (String) redisTemplate.opsForValue().get(cacheKey);if (userInfo != null) {System.out.println("从缓存中获取数据: " + userInfo);return userInfo;}// 模拟从数据库查询数据userInfo = "用户信息: " + userId;System.out.println("从数据库查询数据: " + userInfo);// 将数据存入缓存,设置过期时间redisTemplate.opsForValue().set(cacheKey, userInfo, 10, TimeUnit.MINUTES);return userInfo;}
}
3.5 创建 Controller

创建 Controller 暴露接口:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/user/{userId}")public String getUserInfo(@PathVariable String userId) {return userService.getUserInfo(userId);}
}

4. 测试接口缓存

启动应用后,访问接口测试缓存效果:

  1. 第一次访问 /user/123,会从数据库查询数据并存入缓存
  2. 第二次访问 /user/123,会直接从缓存中获取数据。
输出示例
数据库查询数据: 用户信息: 123
从缓存中获取数据: 用户信息: 123

5. 缓存策略优化

5.1 缓存穿透

问题:请求不存在的数据,导致缓存失效,大量请求直接访问数据库
解决方案
缓存空值:将空值存入缓存,并设置较短的过期时间。
• 布隆过滤器:在缓存层过滤掉不存在的数据。

5.2 缓存雪崩

问题:大量缓存同时失效,导致数据库压力骤增。
解决方案
• 设置随机过期时间:避免缓存同时失效。
• 使用分布式锁:限制数据库访问的并发量。

5.3 缓存击穿

问题:热点数据过期后,大量请求直接访问数据库
解决方案
• 使用互斥锁:只允许一个线程更新缓存,其他线程等待。
• 设置永不过期的热点数据:定期异步更新缓存


6. 总结

通过 Redis 实现接口缓存,可以显著提升接口性能,减少数据库压力。本文详细介绍了如何在 Spring Boot 中集成 Redis,并实现了一个简单的缓存示例。希望这篇博客能帮助你更好地理解和使用 Redis 缓存

如果你有任何问题或建议,欢迎在评论区留言!


http://www.ppmy.cn/ops/166941.html

相关文章

【C++11】深入浅出 std::async

【C11】深入浅出 std::async 一、基本用法 c11中增加了线程&#xff0c;使得我们可以非常方便的创建线程&#xff0c;它的基本用法是这样的&#xff1a; void f(int n); std::thread t(f, n 1); t.join();但是线程毕竟是属于比较低层次的东西&#xff0c;有时候使用有些不便…

机器学习在科研领域的应用与未来趋势:机器学习第一性原理+分子动力学

“机器学习”这个词听起来很高大上&#xff0c;但其实概念很简单&#xff1a;让机器像人一样学习。 机器学习的核心是它的自学习能力&#xff0c;能通过训练从数据中发现规律&#xff0c;为各种科学问题提供创新解决方案。 本文较长&#xff0c;建议先收藏后随时查看&#xff0…

Java学习打卡-Day18-ArrayList、Vector、LinkedList

ArrayList 底层是数组队列&#xff0c;相当于动态数组。 ArrayList 中维护了一个Object 类型的数组elementData transient Object[] elementData; ArrayList 中可以存储任何类型的对象&#xff0c;包括 null 值。不过&#xff0c;不建议向ArrayList 中添加 null 值&#xff0c…

「速通AI编程开发」共学(三):提示词(Prompts)配置项

「速通AI编程开发」共学&#xff08;三&#xff09; 一、共学课程来源学习初衷 二、介绍不同模式下的提示词&#xff08;Prompts&#xff09;支持性提示词 三、提示词学习材料分享 一、共学课程来源 Datawhale通过开源学习模式&#xff0c;助力AI学习者与知识连接&#xff0c;…

Deepseek API+Python测试用例一键生成与导出-V1.0.2【实现需求文档图片识别与用例生成自动化】

在测试工作中&#xff0c;需求文档中的图片&#xff08;如界面设计图、流程图&#xff09;往往是测试用例生成的重要参考。然而&#xff0c;手动提取图片并识别内容不仅耗时&#xff0c;还容易出错。本文将通过一个自研小工具&#xff0c;结合 PaddleOCR 和大模型&#xff0c;自…

超参数优化算法:scikit-opt库、Scikit-Optimize库

1 scikit-opt库&#xff1a;https://www.cnblogs.com/luohenyueji/p/18333387 https://blog.csdn.net/weixin_45750972/article/details/124683402 a 差分进化算法 (Differential Evolution)&#xff1a;一种基于群体搜索的优化算法&#xff0c;通过模拟生物进化的过程来寻找最…

python局部变量和全局变量

文章目录 1.局部变量和全局变量2.局部变量2.1 局部变量的作用2.2 局部变量的生命周期 3. 全局变量3.1 函数不能直接修改全局变量的引用3.2 在函数内部修改全局变量的值3.3 全局变量定义的位置3.4 全局变量命名的建议 1.局部变量和全局变量 &#xff08;1&#xff09;局部变量 …

Spring 创建bean的流程

Bean的创建流程 创建bean流程 Spring 三级缓存 循环依赖的解决流程&#xff1a; 因为成品和半成品对象无法放在都一个map&#xff0c;同时半成品不能暴露出来使用&#xff0c;因此Spring提出三级缓存来解决循环依赖问题 三级缓存定义如下&#xff1a; /** 一级缓存 单例缓存…