Redis 缓存数据库查询的实现
1. 需求背景
- 数据库表
globalship
存储大量船舶信息,每次查询船舶信息时,使用 mmsi
作为查询条件。
- 由于数据量大,直接查询数据库性能较差,计划引入 Redis 缓存优化查询速度。
- 目标:通过
mmsi
查询船舶信息,若 Redis 中存在缓存则直接返回,否则查询数据库,并将结果缓存到 Redis。
2. 实现思路
- 先查询 Redis 缓存:根据
mmsi
在 Redis 中查找船舶信息。如果找到,直接返回缓存结果。
- 查询数据库:如果 Redis 中没有对应的缓存,则查询数据库,获取船舶信息。
- 缓存结果到 Redis:将数据库查询的结果写入 Redis,并设置缓存的过期时间,防止数据长期占用 Redis 内存。
- 返回结果:返回缓存或数据库查询的结果。
3. Redis 缓存代码实现
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 GlobalShipService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private GlobalShipRepository globalShipRepository;
private static final String REDIS_PREFIX = "globalship:";
private static final long CACHE_EXPIRATION = 1;
public GlobalShip getShipByMmsi(Long mmsi) {
String redisKey = REDIS_PREFIX + mmsi;
GlobalShip globalShip = (GlobalShip) redisTemplate.opsForValue().get(redisKey);
if (globalShip != null) {
return globalShip;
}
globalShip = globalShipRepository.findByMmsi(mmsi);
if (globalShip != null) {
redisTemplate.opsForValue().set(redisKey, globalShip, CACHE_EXPIRATION, TimeUnit.HOURS);
}
return globalShip;
}
}
4. 代码实现关键点
- Redis 缓存查询:
redisTemplate.opsForValue().get(redisKey)
,根据 mmsi
查询 Redis。
- 数据库查询:
globalShipRepository.findByMmsi(mmsi)
,当 Redis 中没有数据时,查询数据库。
- 缓存写入:
redisTemplate.opsForValue().set(redisKey, globalShip, CACHE_EXPIRATION, TimeUnit.HOURS)
,将数据库查询结果写入 Redis,设置 1 小时的缓存过期时间。
5. 优化措施
- 防止缓存穿透:如果数据库查询结果为空,可以缓存一个标志,防止重复查询同样的无效数据。例如,缓存空对象或特定标志。
if (globalShip == null) {
redisTemplate.opsForValue().set(redisKey, "NOT_FOUND", CACHE_EXPIRATION, TimeUnit.HOURS);
}
- 缓存雪崩防护:给不同的缓存键设置随机过期时间,避免大量缓存同时过期,导致 Redis 负载过高。
long expirationTime = CACHE_EXPIRATION + new Random().nextInt(30);
redisTemplate.opsForValue().set(redisKey, globalShip, expirationTime, TimeUnit.HOURS);
- 批量查询和缓存:如果可以,尽量减少单条查询和缓存,使用批量查询和缓存的方式,提高性能。
6. 注意事项
- 缓存更新策略:当数据库中的数据发生变化时,需要更新 Redis 中的缓存,可以采用写操作后清除对应缓存或定时刷新缓存的机制。
- 缓存大小控制:要注意控制 Redis 的内存使用,设置合理的过期时间和内存淘汰策略,防止 Redis 被大量缓存数据占用。
7. 适用场景
- 适用于数据量大、查询频繁但数据变化不频繁的场景,如船舶信息、商品信息等场景。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!