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

【13/20】缓存与性能优化:Redis 在 Express 中的整合,实现用户数据缓存

标签:缓存、性能优化、Redis、Express、数据缓存、入门教程、项目实践

前言

欢迎来到“前后端与数据库交互详解”系列的第13篇文章!在前十二篇文章中,我们构建了从Vue.js前端到Express后端、MongoDB数据库的全栈应用,包括JWT认证、Vuex状态管理、WebSocket实时聊天和聚合报告生成。现在,应用已有分析功能,但高频查询(如报告)可能导致数据库负载过高。

本篇文章的焦点是 缓存与性能优化,特别是用Redis在Express中的整合,实现用户数据缓存。我们将解释Redis是什么、如何作为缓存层,并在结尾扩展第十二篇的项目:添加Redis缓存用户统计报告(从聚合查询),减少MongoDB访问,提升响应速度。这将形成一个更高效的full-stack应用。未来,我们将探索安全强化。

前提:您已安装Redis服务器(下载自redis.io,运行redis-server)。Node.js项目安装redis客户端:npm install redis。项目基于第十二篇的后端(带聚合)和前端(带Vuex)。

一、缓存与性能优化是什么?

缓存是临时存储频繁访问的数据,以减少数据库查询的机制;性能优化涉及降低延迟、负载,如用缓存、索引。

  • 为什么需要Redis?

    • 缓存优势:内存存储,快(毫秒级);适合会话、查询结果;过期机制(TTL)自动失效。
    • Redis 特点:键值存储,支持数据结构(如字符串、列表、哈希);高可用(集群);比Memcached更丰富。
    • 对比其他:浏览器localStorage(客户端);我们用Redis作为服务器端缓存。
    • 安全考虑:配置密码;避免敏感数据缓存;用TLS加密。
    • 在full-stack中的作用:后端检查缓存(hit返回,miss查询DB并缓存);前端无大改。
    • 与前文整合:缓存第十二篇的聚合报告,结合认证(仅缓存授权数据)。
  • 核心概念

    • 客户端:const redis = require(‘redis’).createClient();
    • 操作:set(key, value, ‘EX’, ttl)存储;get(key)获取。
    • JSON处理:用JSON.stringify/JSON.parse序列化对象。
    • 缓存策略:Cache-Aside(应用管理:读时查缓存,无则DB+缓存);失效(set TTL)。
    • 在优化中的作用:如缓存用户统计,减少聚合查询开销。

在我们的系列中,Redis优化报告生成,适合高并发聊天系统。

二、缓存与性能优化的基本使用

  1. 连接Redis:createClient({ url: ‘redis://localhost:6379’ })。
  2. 存储:await client.set(key, JSON.stringify(data), { EX: 3600 }) // 1小时过期。
  3. 获取:const data = JSON.parse(await client.get(key))。
  4. 错误处理:client.on(‘error’, err => console.log(err))。

示例:缓存用户计数 if (cached) return cached; else { data = await User.countDocuments(); await client.set('userCount', JSON.stringify(data), { EX: 60 }); }

接下来,通过项目实践这些。

三、实现完整项目:带Redis缓存的认证用户聊天报告系统

项目目标:扩展第十二篇的Express后端和Vue前端,添加Redis缓存用户统计报告(从聚合管道)。缓存键基于查询参数,只有管理员访问;TTL 5分钟(假设报告数据不需实时)。这是一个独立的完整高效full-stack应用。

步骤 1: 后端准备(扩展Express项目)

基于第十二篇的Express项目,安装redisnpm install redis

新建Redis工具(utils/redis.js):

const redis = require('redis');const client = redis.createClient({ url: 'redis://localhost:6379' });
client.on('error', (err) => console.log('Redis Client Error', err));
client.connect(); // 异步连接module.exports = client;

更新报告路由(routes/reports.js,从第十二篇):

const express = require('express');
const router = express.Router();
const User = require('../models/User');
const authMiddleware = require('../middleware/auth');
const redisClient = require('../utils/redis'); // 新增router.get('/user-stats', authMiddleware, async (req, res) => {try {if (req.user.role !== 'admin') return res.status(403).json({ msg: '无权限' });const cacheKey = 'userStats'; // 简单键;可基于参数动态// 检查缓存const cachedData = await redisClient.get(cacheKey);if (cachedData) {return res.json(JSON.parse(cachedData));}// 无缓存,执行聚合const pipeline = [{ $match: { role: { $ne: 'admin' } } },{$group: {_id: { $dateToString: { format: '%Y-%m', date: '$createdAt' } },totalUsers: { $sum: 1 },activeUsers: {$sum: {$cond: [{ $gte: ['$lastLogin', new Date(new Date() - 30 * 24 * 60 * 60 * 1000)] }, 1, 0]}}}},{ $sort: { _id: 1 } }];const stats = await User.aggregate(pipeline);// 缓存结果,TTL 300秒(5分钟)await redisClient.set(cacheKey, JSON.stringify(stats), { EX: 300 });res.json(stats);} catch (err) {res.status(500).json({ msg: '服务器错误' });}
});module.exports = router;
  • 解释:先查Redis(hit直接返回);miss时聚合MongoDB并缓存;整合authMiddleware。

步骤 2: 前端准备(扩展Vue项目)

基于第十二篇的Vue项目,无需大改Vuex(fetchUserStats仍调用API);后端缓存透明优化性能。前端可添加加载指示,但这里保持简单。

步骤 3: 更新报告组件(可选细化)

src/components/UserReport.vue(从第十二篇),添加缓存提示(非必需):

<!-- ... 同第十二篇 -->
<template><!-- ... --><p v-if="userStats.length">数据从缓存加载(如果可用)</p>
</template>

步骤 4: 运行和测试

  • Redis:运行redis-server(localhost:6379)。
  • 后端:node server.js(localhost:3000,确保MongoDB运行)。
  • 前端:npm run serve(localhost:8080)。
  • 测试:作为admin访问/report,首次fetchUserStats击中MongoDB并缓存;刷新(<5min)击中Redis(更快);过期后重新查询;用Redis CLI(如redis-cli GET userStats)验证缓存;高频访问观察性能提升。
  • 这是一个完整的带缓存优化的full-stack应用!Redis无缝整合报告端点,减少DB负载。

步骤 5: 扩展(可选)

  • 动态键:cacheKey = userStats:${req.query.month} 支持参数缓存。
  • 失效:用户更新时del(key)手动失效。
  • 更多缓存:缓存用户列表或WebSocket房间数据。
  • 监控:用Redis Insight工具查看命中率。

四、常见问题与调试

  • Redis连接失败?检查redis-server运行、URL正确;console.log错误。
  • 缓存不生效?验证set/get键匹配、TTL未过期;JSON.parse错误检查序列化。
  • 数据不一致?设置合适TTL;实现缓存失效逻辑。
  • 性能瓶颈?Redis单线程;用集群大规模。

总结

通过本篇,您入门了缓存与性能优化,用Redis实现用户数据缓存。带缓存的认证聊天报告系统证明了高效full-stack应用。

下一篇文章:安全强化:HTTPS 和率限制在 Express 中的应用,实现防护机制。我们将添加HTTPS加密和限流,增强应用安全。如果有疑问,欢迎评论!

(系列导航:这是第13/20篇。关注我,跟着学完整系列!)

http://www.dtcms.com/a/390873.html

相关文章:

  • 如何防止电脑长时间运行过热?定时关机是第一道防线
  • 开源监控利器Prometheus+Grafana在银河麒麟操作系统的落地实践
  • 小程序移动端设计UI(一)预约小程序——东方仙盟练气期
  • Android13 命令启用WLAN详细日志分析
  • 临床AI产品化全流程研究:环境聆听、在环校验与可追溯系统的多技术融合实践(中)
  • 深度解读昇腾CANN动态Shape图调度加速技术
  • linux系统使用ImageMagick注意,只能使用convert命令
  • [Windows] 搜狗拼音一键净化
  • Go语言25个关键字全解析
  • 图像滤波常用总结
  • Go语言设计原则与设计模式
  • (LoRA深度解析)LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS论文精读(逐段解析)
  • 第十四届蓝桥杯青少组C++选拔赛[2022.11.27]第二部分编程题(4、找路线)
  • 知识图谱对自然语言处理深层语义分析的影响与启示:结构化研究报告
  • 架构师成长之路-缓存二
  • 正点原子小智BOX0/BOX2 产品使用视频表情功能
  • 鸿蒙NEXT分布式文件系统:开启跨设备文件访问新时代
  • 【主机初始化工作】
  • Ubuntu20.04仿真 | iris四旋翼添加livox mid360激光雷达
  • Linux进程终止
  • Go如何重塑现代软件开发的技术基因
  • 设计模式(C++)详解—外观模式(2)
  • 【ubuntu24.04】apt update失败 过期的签名清理
  • Go 语言常用算法库教学与实践指南
  • 基于FPGA的智能垃圾分类装置
  • 168. Excel 表列名称【简单】
  • Ubuntu20.04 6步安装ROS-Noetic
  • 基于 MATLAB 的双边滤波去图像云雾处理
  • 将一台已连接无线网络的 Windows 电脑通过网络线共享网络给另一台电脑
  • 复习1——TCP/IP之常用协议