使用 Redis 在 Node.js 中进行缓存
在本文中,我们将使用 Redis 在 Node.js 应用程序中实现缓存,但在深入研究实现细节之前,让我们先探讨一下什么是缓存以及它如何帮助提高应用程序的性能。
什么是缓存?
缓存是将文件副本存储在缓存或临时存储位置,以便更快地访问的过程。 - Cloudflare
现在我们了解了缓存是什么,让我们来探讨一下缓存的原因
我们为什么要缓存?
鉴于如今互联网上为用户提供的超快服务和选项众多,您肯定不希望自己的应用响应用户请求的时间过长,否则用户可能会转而使用竞争对手的服务,导致跳出率持续上升,而收入却无法增长。
以下是我们使用缓存的一些原因:
- 为了节省成本。例如支付带宽费用,甚至是网络传输的数据量费用。
- 减少应用程序响应时间。
总的来说,以正确的方式进行缓存将提高我们应用程序的性能,并为我们和我们的用户带来双赢的局面。
先决条件
要完成本教程,您必须在计算机上安装以下软件
- 节点 JS
- 新公共管理
- Postman/Web浏览器
- 代码编辑器 (VsCode)
如果您尚未安装 Node.js,请前往Node.js官方网站获取适用于您平台的 Node.js 版本。安装 Node.js 后,npm 也会自动安装。
入门 首先
,通过在终端上运行以下命令为应用程序创建一个新目录:
cd desktop && mkdir node-caching && cd node-caching
上面的命令
cd desktop - 导航到桌面目录
mkdir node-caching - 创建一个名为“node-caching”的新目录
cd node-caching - 导航到新创建的 node-caching 目录
通过运行以下命令初始化目录以创建 package.json 文件
npm init -y
安装依赖项
对于这个项目,我们将使用 Redis、axios 和 Express Framework for Node.js,因此让我们通过运行以下命令来安装它们:
npm install express redis axios
在您选择的编辑器中打开新创建的文件夹。
您的文件夹结构现在应如下所示:
创建一个简单的 Express 服务器,如下所示:
const express = require('express'); | |
const app = express(); | |
const port = 3000; | |
app.listen(port, () => { | |
console.log(`Server running on port ${port}`); | |
}); | |
module.exports = app; |
我们将向公共 API 请求http://www.recipepuppy.com提供的各种食品食谱
在 index.js 文件中粘贴以下代码:
通过运行 node index.js 启动服务器并打开 postman 向配方端点发出请求
可以看到,请求耗时615 毫秒,对于获取不经常变化的数据来说,这个时间相当长。我们将使用 Redis 实现缓存来改进这个问题。
为了充分利用 Redis 的功能,我们需要直接从源代码编译 Redis。请在终端上运行以下命令:
wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make
通过运行确认安装
make test
然后可以通过运行以下命令将 redis 复制到您的路径sudo make install
要确认 redis 已正确设置,请运行以下命令启动 redis 服务器
redis-server
从你的终端。然后打开一个新的终端选项卡/窗口并运行
redis-cli ping
您应该会收到PONG作为回应。
有关详细的设置说明,请访问网站上的官方指南https://redis.io/topics/quickstart
现在我们已经正确设置了 redis,下一步就是在我们的应用程序中使用它来通过减少请求和响应的周转时间来改进它。
将以下更改添加到 index.js 文件
解释缓存过程
首先我们创建一个redis客户端,并使用默认的redis端口(6379)将其与本地redis实例链接起来
const client = redis.createClient(6379);
然后,在/recipe路由处理程序中,我们尝试通过检查 Redis 存储中的键来获取合适的匹配数据来处理请求。如果找到,则将结果从缓存中提供给请求的客户端,这样我们就不必再向服务器发出请求了。
// Check the redis store for the data first
client.get(foodItem, async (err, recipe) => {
if (recipe) {
return res.status(200).send({
error: false,
message: `Recipe for ${foodItem} from the cache`,
data: JSON.parse(recipe)
})
}
但是,如果在我们的 redis 存储中找不到该密钥,则会向服务器发出请求,一旦收到响应,我们就会使用 redis 存储中的唯一密钥存储结果:
const recipe = await axios.get(`http://www.recipepuppy.com/api/?q=${foodItem}`);
// save the record in the cache for subsequent request
client.setex(foodItem, 1440, JSON.stringify(recipe.data.results));
因此,只要缓存数据未过期,对同一端点使用相同参数的后续请求始终会从缓存中获取。Redis 客户端的 setex 方法用于设置键,使其在存储中保存特定秒数的字符串值,在本例中为 1440 秒(24 分钟)。Redis
可用命令和选项的完整列表可在此处找到:https://redis.io/commands
测试应用程序
现在让我们测试一下实现缓存后的应用程序。打开 Postman 并向与之前相同的端点发出请求。
同样,由于在缓存中找不到该键,请求被发送到服务器,耗时 566 毫秒。由于该键之前在缓存中不存在,因此现在将其保存在缓存中,后续具有相同数据的请求将从缓存中获取,这不仅提高了速度,还减轻了服务器的负载。以下是缓存后的响应时间:
正如我们上面看到的,由于请求是从缓存中获取的,因此需要 3毫秒才能完成。
现在告诉我,您不想开始缓存吗?
请注意,这只是我们用 redis 所能做的冰山一角,我建议您查阅官方文档https://redis.io/documentation以充分享受这个惊人的数据存储的全部功能。
完整代码可以在这里找到https://github.com/iMichaelOwolabi/node-redis-caching-tut
文章来源:https://dev.to/imichaelowolabi/caching-in-node-js-using-redis-o1b