Redis 缓存数据库查询的实现

news/2024/9/24 21:20:16

Redis 缓存数据库查询的实现

1. 需求背景

  • 数据库表 globalship 存储大量船舶信息,每次查询船舶信息时,使用 mmsi 作为查询条件。
  • 由于数据量大,直接查询数据库性能较差,计划引入 Redis 缓存优化查询速度。
  • 目标:通过 mmsi 查询船舶信息,若 Redis 中存在缓存则直接返回,否则查询数据库,并将结果缓存到 Redis。

2. 实现思路

  1. 先查询 Redis 缓存:根据 mmsi 在 Redis 中查找船舶信息。如果找到,直接返回缓存结果。
  2. 查询数据库:如果 Redis 中没有对应的缓存,则查询数据库,获取船舶信息。
  3. 缓存结果到 Redis:将数据库查询的结果写入 Redis,并设置缓存的过期时间,防止数据长期占用 Redis 内存。
  4. 返回结果:返回缓存或数据库查询的结果。

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 {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate GlobalShipRepository globalShipRepository; // 假设这是数据库操作接口private static final String REDIS_PREFIX = "globalship:"; // Redis 键的前缀private static final long CACHE_EXPIRATION = 1; // 缓存过期时间,单位:小时public GlobalShip getShipByMmsi(Long mmsi) {String redisKey = REDIS_PREFIX + mmsi;// 1. 查询 Redis 缓存GlobalShip globalShip = (GlobalShip) redisTemplate.opsForValue().get(redisKey);if (globalShip != null) {// 缓存命中,直接返回return globalShip;}// 2. 如果缓存没有命中,查询数据库globalShip = globalShipRepository.findByMmsi(mmsi);if (globalShip != null) {// 3. 数据库查询结果缓存到 Redis,设置缓存过期时间redisTemplate.opsForValue().set(redisKey, globalShip, CACHE_EXPIRATION, TimeUnit.HOURS);}// 4. 返回结果(缓存或数据库查询结果)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); // 随机过期时间,1小时到1小时30分钟
redisTemplate.opsForValue().set(redisKey, globalShip, expirationTime, TimeUnit.HOURS);
  • 批量查询和缓存:如果可以,尽量减少单条查询和缓存,使用批量查询和缓存的方式,提高性能。

6. 注意事项

  • 缓存更新策略:当数据库中的数据发生变化时,需要更新 Redis 中的缓存,可以采用写操作后清除对应缓存或定时刷新缓存的机制。
  • 缓存大小控制:要注意控制 Redis 的内存使用,设置合理的过期时间和内存淘汰策略,防止 Redis 被大量缓存数据占用。

7. 适用场景

  • 适用于数据量大、查询频繁但数据变化不频繁的场景,如船舶信息、商品信息等场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/64336.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

redis内容记录

redis的基本数据类型String:是最基本的数据类型,它可以存储任何二进制安全的数据。 不仅能存放文本数据,还能保存图片、音频、视频、压缩文件等二进制数据。它们通常用于缓存。 Hash:哈希类型,其中键值对中的值本身又是一个键值对结构,hash 特别适合用于存储对象。 List:…

人工智能教育技术学第四周

1.用亿图图示制作黄山奇石语文课文的思维导图2.CAJViewer9.2(CAJ全文浏览器)是中国知网的专用全文格式阅读器,CAJ浏览器支持中国期刊网的CAJ、PDF、KDH等多种格式文件阅读。并且它的打印效果与原版的效果一致。可实现页面设置、浏览页面、查找文字、切换显示语言、文本摘录、…

项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统)

需求1.使用osg三维引擎进行动力学模型仿真性能测试;  2.打开动力学仿真模型文件,.k后缀的模型文件,测试加载解析过程;  3.解决第三方company的opengl制作的三维引擎,绘制面较多与弹丸路径模拟较卡顿的问题;  4.测试时,使用的模型为公开模型,基础面数量达到160多万…

【入门岛第1关】linux 基础知识

目录闯关任务 完成SSH连接与端口映射并运行hello_world.py 闯关任务 完成SSH连接与端口映射并运行hello_world.py 1 在远程主机上建立hello_python.py程序并运行,查看程序运行的端口: import socket import re import gradio as gr# 获取主机名 def get_hostname():hostname …

DOTS计算Voronoi图形生成,根据点自动划分区域生成多边形

如图,生成Voronoi图形,代码如下。using UnityEngine; using Unity.Mathematics; using Unity.Jobs; using Unity.Collections; using Unity.Profiling;[ExecuteInEditMode] public class VoronoiTextureBurstJobComponent : MonoBehaviour {[SerializeField][Min(1)] uint _s…

Vue2+3基础

。第一个Vue程序 使用script进行Vue全局设置: 指定Vue实例挂载的位置 , Vue和js一样,都需要在script里写 第一步创建vue实例 1.为什么要new vue(),直接调用Vue不行吗?不行,因为如果直接调用Vue()会报如下错误: 2.关于vue构造函数:optionsoptions翻译为多个选项 Vue…

任务4:制作二维码

该二维码链接到游戏“植物大战僵尸”,寓教于乐。 提升趣味性和互动性的同时,学生们参与到课堂当中,发挥主体作用,感受到自然界植物的多样性,对土壤的作用有了更深刻的理解。

封装的练习题目1

1.使用面向对象的思想,编写自定义描述狗的信息。设定属性包括:品种,年龄,心 情,名字;方法包括:叫,跑。 要求: 1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问 2)限定心情只能有“心情好”和“心情不好”两种情况,如果无效输入进行提示, 默认…