node 使用 Redis 缓存
缓存是什么?
高并发下,一个项目最先出问题的,并不是程序本身,而是数据库最先承受不住。
在数据库上我们可以做很多优化,例如优化 SQL 语句,优化索引,如果数据量大了,还可以分库、分表等等。
一个项目中,大多数使用场景都是查询操作,而不是其他新增、修改和删除。那我们思考一下,能不能在第一次查询后,将数据存储在某个地方。下次再查询的时候,就直接读取之前保存的。如果数据发生改变了,就保存的数据删掉,重新保存最新的。这样不就可以大幅度的减少数据库的查询吗?
缓存就是这个原理。
Redis 又是什么?
Redis是一个开源的、基于内存的数据存储系统,可以用作数据库、缓存和消息中间件。Redis的数据都存储在内存中,这样它的读写速度就非常快。而且还会将内存中的数据写入本地硬盘,可以在服务器重启后,自动将数据恢复到内存中。学习
Redis是大家成为高手的必经之路。它的功能非常强大,在我们这节课中,只会用到Redis的缓存能力。
如何安装 Redis 的服务端与客户端?
1、安装 Redis 服务端 Windows Docker Desktop安装及使用 Docker 运行 MySQL
运行Redis,最推荐的方式依然是使用Docker。打开项目根目录的docker-compose.yml文件,添加Redis的相关配置。大家注意下格式,缩进非常重要,一定是和之前的MySQL配置对齐的
services:mysql:# ....redis:image: redis:7.4ports:- "6379:6379"volumes:- ./data/redis:/data
完成后,命令行,再次运行
docker-compose up -d
这样Docker,就会自动下载好Redis,并在6379端口启动它。

2、安装 Redis 客户端
服务端启动好了,还需要用客户端进行管理。所谓客户端,就是像 Navicat、Sequel Ace 一样用来管理数据库的工具。这里推荐大家使用的客户端,叫做Redis Insight,它是 Redis 官方发布的管理工具。它是完全免费的,非常好用。
Redis Insight官网


双击一下,就可以连进去了。

目前里面还没有存任何东西进去,所以都是空白的。好了,先丢一边,一会儿我们再来继续用它。
如何在 Node 项目中,使用 Redis 缓存数据?
Redis已经安装,并启动好了以后,现在需要在Node项目中来操作它。
1、安装 node-redis
项目根目录
npm i redis
2、Redis 配置文件
接着看官方文档

- 这里告诉我们了,使用前,要先用
connect方法连接上去。 - 用
set来写入数据。 - 用
get来读取数据。 key,就是给缓存数据,取了个名字。无论写入,还是读取,都是用这个名字,就能找到它。- 不用了以后,可以用
disconnect方法来断开连接。
新建utils/redis.js,内容我已经写好了
const {createClient} = require('redis');// 创建全局的 Redis 客户端实例
let client;/*** 初始化 Redis 客户端*/
const redisClient = async () => {if (client) return; // 如果客户端已经初始化,则不再重复初始化client = await createClient().on('error', err => console.log('Redis 连接失败', err)).connect();
};/*** 存入数组或对象,并可选地设置过期时间* @param key 键名* @param value 要存储的值* @param ttl 可选,以秒为单位的过期时间,默认不设置*/
const setKey = async (key, value, ttl = null) => {if (!client) await redisClient(); // 确保客户端已初始化value = JSON.stringify(value); // 将对象转换为JSON字符串await client.set(key, value);// 如果提供了ttl,则设置过期时间if (ttl !== null) {await client.expire(key, ttl);}
};/*** 读取数组或对象* @param key 键名* @returns {Promise<any>} 解析后的JSON对象或数组*/
const getKey = async (key) => {if (!client) await redisClient(); // 确保客户端已初始化const value = await client.get(key); // 将获取到的JSON字符串转换回对象return value ? JSON.parse(value) : null; // 如果value为空,返回null而不是抛出错误
};/*** 清除缓存数据* @param key* @returns {Promise<void>}*/
const delKey = async (key) => {if (!client) await redisClient(); // 确保客户端已初始化await client.del(key);
};/*** 获取匹配模式的所有键名* @param pattern* @returns {Promise<*>}*/
const getKeysByPattern = async (pattern) => {if (!client) await redisClient();return await client.keys(pattern);
}/*** 清空所有缓存数据* @returns {Promise<void>}*/
const flushAll = async () => {if (!client) await redisClient();await client.flushAll();
}module.exports = {redisClient, setKey, getKey, delKey, getKeysByPattern, flushAll};
- 先定义了一个
client变量,里面会创建全局的Redis客户端实例。 - 第一个方法,是用来连接到了
Redis的。这里有一个判断,如果已经存在了,就直接返回,这样可以避免重复的创建 Redis 实例。 - 接着我们自定义了写入数据的方法,需要注意的是,在存储之前,先要用
JSON.stringify()方法将 JS 对象或数组转换成JSON 字符串。 - 下面还有过期时间的设置,不传就是永久的。如果传了,以秒为单位,如果时间超出后,
Redis会自动清理掉存储的数据。 - 读取方法里,使用
JSON.parse()方法将JSON 字符串解析回原来的数据结构。 - 最下面是删除缓存的方法,调用
del方法,即可删掉缓存数据。
这样做好封装好后,用起来就非常简单了,而且就算是数组或对象,也可以顺利的存取了。
PS: 如果您的 Redis 服务端,运行在其他服务器上或者你在宝塔中不想使用docker,可以调整连接格式为:
client = await createClient({url: 'redis://<服务器IP>:<端口号>' ,// password:'', 有无密码
})

3、通过utils/redis.js使用
// 引入
const { setKey, getKey } = require('../utils/redis');
// 单条数据存储 key:键名 data:数据
setKey(key, data);
// 带有效期存储 key:键名 data:数据 ttl:时间s为单位
setKey( key, data, ttl);
// 带分页的缓存 articles:默认为路由名 后用:链接 当前页和当页数量 (预定俗称以:为连接)
const cacheKey = `articles:${currentPage}:${pageSize}`;
setKey(cacheKey, data);
// 带id 的缓存 articles:默认为路由名 后用:链接 当前id (预定俗称以:为连接)
setKey(`article:${id}`, data)// 单条数据删除 key:键名
await delKey(key);// 复杂缓存删除
/*** 清除缓存* @param id* @returns {Promise<void>}*/
async function clearCache(id = null) {// 清除所有文章列表缓存 let keys = await getKeysByPattern('articles:*');if (keys.length !== 0) {await delKey(keys);}// 如果传递了id,则通过id清除文章详情缓存if (id) {// 如果是数组,则遍历const keys = Array.isArray(id) ? id.map(item => `article:${item}`) : `article:${id}`;await delKey(keys);}
}相关文章:
node 使用 Redis 缓存
缓存是什么? 高并发下,一个项目最先出问题的,并不是程序本身,而是数据库最先承受不住。 在数据库上我们可以做很多优化,例如优化 SQL 语句,优化索引,如果数据量大了,还可以分库、分表…...
PMBOK第7版整体架构全面详解
1. 引言 7月1日对于项目管理从业者和研究者而言,是个非凡意义的一个时间,这一天,翘首以待的《 项 目管理知识体系指南 》(PMBOK)第七版终于发布了。 总体而言,PMBOK第七版集百家之所长,成一…...
【Scrapy】Scrapy教程6——提取数据
前一小节我们拿到了页面的数据,那页面中那么多内容,我们想要其中的部分内容,该如何获取呢?这就需要对我们下载到的数据进行解析,提取出来想要的数据,这节就讲讲如何提取数据。 引入 我们编辑保存下来的shouye.html文件看下,发现这是什么鬼,全是如下图的代码。 没错…...
golang panic信息捕获
背景 我们的日志接入阿里云sls平台,但是,日志是以json的格式存储在阿里云sls平台上,程序中产生的error,info等日志都可以实现以json的格式打印。但是,golang程序中产生的panic信息本身不是以json的格式输出,这就导致p…...
一周学会Flask3 Python Web开发-http响应状态码
锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在Flask程序中,客户端发出的请求触发相应的视图函数,获取返回值会作为响应的主体,最后生成…...
goland无法debug项目
1、其实个原因是因为正在使用的Delve调试器版本太旧,无法兼容当前的Go语言版本1.2。Delve是Go语言的一个调试工具,用于提供源码级别的调试功能。Go语言每隔一段时间会发布新版本,而相应的调试器Delve也可能会更新以提供新的特性或修复已知问题…...
迪威模型网:免费畅享 3D 打印盛宴,科技魅力与趣味创意并存
还在为寻找优质3D打印模型而发愁?快来迪威模型网(https://www.3dwhere.com/),一个集前沿科技与无限趣味于一体的免费3D打印宝藏平台! 踏入迪威模型网,仿佛开启一场未来科技之旅。其“3D打印”专区ÿ…...
Python VsCode DeepSeek接入
Python VsCode DeepSeek接入 创建API key 首先进入DeepSeek官网,https://www.deepseek.com/ 点击左侧“API Keys”,创建API key,输出名称为“AI” 点击“创建",将API key保存,复制在其它地方。 在VsCode中下载…...
Java中JDK、JRE,JVM之间的关系
Java中的JDK、JRE和JVM是三个核心概念,其关系可概括为JDK > JRE > JVM,具体如下: 一、定义与作用 JDK(Java Development Kit) 定义:Java开发工具包,用于开发和编译Java程序。包含内容&…...
Ubuntu22.04.6如何固定ip地址
Ubuntu22.04.6如何固定ip地址 主要参见这篇博客 ubuntu 桌面版如何设置固定IP地址_ubuntu桌面版如何修改ip-CSDN博客 1.先查看一下当前的IP是多少...
腿足机器人之十- SLAM地图如何用于运动控制
腿足机器人之十- SLAM地图如何用于运动控制 腿足机器人SLAM地图的表示与处理全局路径规划:地形感知的路径搜索基于A*的三维路径规划基于RRT*的可行步态序列生成 局部运动规划:实时步态调整与避障动态窗口法的腿足适配模型预测控制(MPC&#x…...
毕业项目推荐:基于yolov8/yolov5/yolo11的果蔬检测识别系统(python+卷积神经网络)
文章目录 概要一、整体资源介绍技术要点功能展示:功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出(xls格式)功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…...
pyside6学习专栏(二):程序图像资源的加载方式
pyside6中的QLabel控件可以加载图像和gif动画,可以直接从外部文件加载,也可以从QRC类型的文件(实际是一脚本文件)经编绎生成对应的资源.PY模块文件(就是将qrc文本中指定的资源文件的16制内容写入.py文件)来使用,本文对两种方式作了一简单的示…...
vue2和vue3的按需引入的详细对比通俗易懂
以下是 Vue2 与 Vue3 按需引入的对比详解,用最简单的语言和场景说明差异: 一、按需引入的本质 目标:只打包项目中实际用到的代码(组件、API),减少最终文件体积。类比:去餐厅点餐,只…...
JAVA:Gson:序列化和反序列化
Gson 是 Google 提供的一个用于在 Java 中方便地进行 JSON 与对象互相转换的库。 Gson 并不是 Android Studio(AS)专用的库,它是一个 通用的 Java JSON 解析库,可以在 任何 Java 项目 中使用。基本用法如下: 1. 把 Ja…...
如何在 VS Code 中快速使用 Copilot 来辅助开发
在日常开发中,编写代码往往是最耗时的环节之一。而 GitHub Copilot,作为一款 AI 编码助手,可以帮助开发者 自动补全代码、生成代码片段,甚至直接编写完整的函数,大幅提升编码效率。那么,如何在 VS Code 中快…...
PyCharm 中的 %reset -f 功能:一键重置控制台变量
在 PyCharm 的日常使用中,我们经常需要在控制台中测试和运行各种代码片段。随着时间的推移,控制台中会积累大量的变量和输出,这可能会使得环境变得混乱,影响我们的开发效率。为了解决这个问题,IPython 提供了一个非常有…...
DeepSeek-R1论文阅读及本地调用
前言 DeepSeek已经火了一段时间了,对于这项“国运级”的技术成果,即便研究的不是这个方向,也不免好奇前来看看。本文将先解析一下DeepSeek-R1这篇论文,再对DeepSeek的本地部署使用进行研究配置。 论文标题:DeepSeek-…...
自然语言处理:第九十二章 chatBI 经验(转载)
本人项目地址大全:Victor94-king/NLP__ManVictor: CSDN of ManVictor 原文连接: 一文分享 ChatBI 实践经验 写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!! 写在前面: 笔者更新不易,希望走过路过点个关注和赞&#x…...
体验用ai做了个python小游戏
体验用ai做了个python小游戏 写在前面使用的工具2.增加功能1.要求增加视频作为背景。2.我让增加了一个欢迎页面。3.我发现中文显示有问题。4.我提出了背景修改意见,欢迎页面和结束页面背景是视频,游戏页面背景是静态图片。5.提出增加更多游戏元素。 总结…...
sql server 从库创建的用户名登录后访问提示数据库无权限
在主副本库创建登录名并且用户映射赋权指定的数据库权限,副副本库也创建登录名,主副本有权限访问数据库的权限,但是副副本没有权限访问数据库。 解决方案: 检查数据库用户是否映射到登录名 如果数据库用户已存在,但…...
懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)
1.合集懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制):https://www.bilibili.com/video/BV1M6rdYEEog/ 备注: 1.本地离线卡密采用最安全的非对称加解密技术,设备id采用最安全多重混合加密不可逆技术生成&…...
Git LFS介绍(Large File Storage)大文件扩展,将大文件存储在外部存储,仓库中只记录文件的元数据(大文件的指针,类似一个小的占位符文件)
文章目录 LFS的功能?如何使用LFS?将大文件存储在外部系统是什么意思?具体是如何运作的?为什么要这样做? 对开发者的影响?1. **性能和效率**2. **协作体验**3. **版本管理差异**4. **额外的工具和配置** LFS…...
前后端项目部署服务器(传统部署和Docker部署)
内外网 开发环境连外网(8.140.26.187),测试/生产环境连内网(172.20.59.17) 内外网地址不同,但指定的库是同一个 内网IP地址范围包括: 10.0.0.0 到 10.255.255.255172.16.0.0 到 172.31.2551…...
python-leetcode 39.二叉树的直径
题目: 给定一棵二叉树的根节点,返回该树的直径。 二叉树的直径是指中间任意两个节点之间最长路径的长度。这条路径可能经过也可能不经过根节点root 两节点之间路径的长度由他们之间的边数表示 方法一:深度优先搜索 一条路径的长度为该路…...
Webpack的持久化缓存机制具体是如何实现的?
Webpack 的持久化缓存机制是 Webpack 5 引入的一项重要特性,旨在提高构建速度和性能。通过将构建结果缓存到磁盘上,Webpack 可以在后续构建中重用先前的结果,减少不必要的重新计算。以下是持久化缓存机制的具体实现和工作原理。 一、持久化缓…...
开题报告——基于Spring Boot的垃圾分类预约回收系统
关于本科毕业设计(论文)开题报告的规定 为切实做好本科毕业设计(论文)的开题报告工作,保证论文质量,特作如下规定: 一、开题报告是本科毕业设计(论文)的必经过程,所有本科生在写作毕业设计(论文)之前都必须作开题报告。 二、开题报告主要检验学生对专业知识的驾驭能…...
【分布式理论11】分布式协同之分布式事务(一个应用操作多个资源):从刚性事务到柔性事务的演进
文章目录 一. 什么是分布式事务?二. 分布式事务的挑战三. 事务的ACID特性四. CAP理论与BASE理论1. CAP理论1.1. 三大特性1.2. 三者不能兼得 2. BASE理论 五. 分布式事务解决方案1. 两阶段提交(2PC)2. TCC(Try-Confirm-Cancel&…...
配置Api自动生成
我的飞书:https://rvg7rs2jk1g.feishu.cn/docx/TVlJdMgYLoDJrsxAwMgcCE14nxt 使用Springfox Swagger生成API,并导入Postman,完成API单元测试 Swagger: 是一套API定义的规范,按照这套规范的要求去定义接口及接口相关信息,再通过可…...
适用于复杂背景的YOLOv8改进:基于DCN的特征提取能力提升研究
文章目录 1. YOLOv8的性能瓶颈与改进需求1.1 YOLOv8的优势与局限性1.2 可变形卷积(DCN)的优势 2. DCN在YOLOv8中的应用2.1 DCN的演变与YOLOv8的结合2.2 将DCN嵌入YOLOv8的结构中2.2.1 DCNv1在YOLOv8中的应用2.2.2 DCNv2与DCNv3的优化 2.3 实验与性能对比…...
