Node.js 高级主题:缓存。
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
使用 Redis 缓存频繁获取的数据,提高服务器性能。
介绍:
Redis 是一个内存数据库,它以键值对格式存储数据,由于数据存储在内存中,因此速度非常快。
Redis 提供诸如字符串、哈希表、列表、集合、有序集合等数据结构。
Redis 是一个开源(BSD 许可)的内存数据结构存储系统,可用作数据库、缓存、消息代理和流式处理引擎。Redis 提供多种数据结构,例如字符串、哈希表、列表、集合、支持范围查询的有序集合、位图、HyperLogLog、地理空间索引和流。Redis 内置了数据复制、Lua 脚本、LRU 淘汰机制、事务以及不同级别的磁盘持久化,并通过Redis Sentinel提供高可用性,并通过Redis Cluster实现自动分区。redi.io
案例用途:
为什么应该在服务器端实现缓存层,以及它将如何提高应用程序的性能。
-
定期缓存
获取频率过高的数据是一种很好的做法,这样可以避免用户等待太久才能获取基本数据。 -
通过使用缓存来减少数据库查询执行次数,不仅可以降低数据库查询次数,还能避免因重复查询返回相同结果而导致数据库不堪重负。
此外,如果您将应用程序托管在费用昂贵的托管服务商处,还能节省宝贵的带宽。 -
提升应用性能
缓存不仅可以提升数据库性能并保护数据库,还能提升整体服务器-客户端性能。
为了更好地理解这一点,假设你的服务器有一个名为 `getArticle` 的路由,每个发送到该路由的请求大约需要半秒(约 500 毫秒)才能获得响应。使用缓存后,第一个请求可能需要半秒或更长时间,但之后的每个请求只需大约 20 毫秒即可完成!是不是很神奇?!
我将使用我自己的应用来验证这一点。
启用缓存 vs. 禁用缓存:
我在服务器上做了一个简单的基准测试(使用单个 API 来查看在不使用缓存的情况下完成请求需要多长时间,然后使用缓存重新测试同一个 API 以查看性能提升)。
上图显示,我的服务器完成请求花费了超过一秒的时间,当然,每次我发出请求时,所需时间都大致相同!
下图是我在服务器 API 中引入缓存机制后的效果,您可以自行查看时间上的变化(我没有更改请求中的任何内容)。
接下来完成相同请求所需的时间已缩短至约 10 毫升,这是一个显著的改进!
希望现在您对在自己的项目中应用这项技术充满热情。
安装:
在您的机器上安装Redis
在 Linux 系统中,您可以通过在终端输入命令来安装它。
sudo apt-get -y install redis
在 macOS 系统中,在终端中输入以下命令
brew install redis
在 Windows 系统中,由于 Redis 并未得到 Windows 官方支持,因此在 Windows 系统上安装 Redis 会比较困难。
Redis 官方不支持 Windows 系统。但是,您可以按照以下说明在 Windows 上安装 Redis 以进行开发。
要在 Windows 上安装 Redis,您首先需要启用 Windows 子系统 Linux 版 ( WSL2
)。WSL2 允许您在 Windows 上原生运行 Linux 二进制文件。要使此方法生效,您需要运行 Windows 10 版本 2004 或更高版本,或者 Windows 11。https://redis.io/docs/getting-started/installation/install-redis-on-windows/
在您的项目中安装 node-Redis:
node-Redis 是一个现代化的、高性能的 Node.js 客户端。
npm install redis
现在我们已经安装了 Redis 和 node-redis 包,让我们用这些强大的工具做一些简单的工作,然后再尝试在实际示例中使用它们!
Redis快速入门:
// IMPORTANT : before you can establish connection to redis,
// you must start the redis-server
const redis = require('redis');
// create client to communicate redis DB
var client = redis.createClient();
client.connect()
// connect and error events
client.on('error', function (err) {
console.log('Something went wrong ', err)
});
client.on('connect', function () {
console.log('Redis Connected!')
});
连接到 Redis 服务器:
要启动 Redis 服务器,您需要在终端中运行:
redis-server
例子:
上面我们创建了一个客户端并启动了与 Redis 服务器的连接,现在我们可以使用所有功能了。
// used to put data into redis
client.set("key" , "some value")
// used to get data from redis
client.get("key")
// output = "some value"
现实生活中的例子:
现在最大的问题是,如何利用 set() 和 get() 这些简单的函数来提高服务器性能?
让我们看看我的服务器(一个用于从 MongoDB Atlas 获取报价并发送回服务器的 Express 服务器)。
本次基准测试来自我自己的报价 API(即将发布在 RapidAPI 中),我们将看看请求 1000、3000 和 5000 个数据文档时所需时间的差异,我将重复测试,这次从缓存中获取相同的数据。
从数据库中检索 1000 个文档耗时近 2 秒。
但是从缓存中获取相同数量的数据仅需 25 毫秒!
从数据库中检索 3000 个文档只用了将近 4 秒钟!
但是从缓存中获取相同数量的数据仅需 45 毫秒!
从数据库中检索 5000 个文档仅用了不到 5 秒钟!
但从缓存中读取,只用了 60 毫秒!
是不是很神奇?
缓存机制:
缓存其实就是在服务器端添加一个额外的层,这个层会拦截数据库即将执行的查询,并检查该查询是否已被缓存。如果已被缓存,则会将缓存的数据作为响应返回,而不会再次向数据库发送查询。如果尚未被缓存,则会将查询发送到数据库执行,并将结果存储在缓存(Redis)中,以供后续请求使用。
所以,为了明确我们想要做什么:
-
使用上述代码将服务器连接到 Redis。
-
我们想要劫持(拦截、中断,随便你怎么称呼)向数据库发送查询的过程,以便判断该查询是否已被缓存。
-
如果数据已缓存,则返回缓存数据并结束响应。不要向数据库发送任何内容。
-
如果查询未缓存,则发送查询以执行查询并将结果作为响应发送,然后将结果存储在缓存中以供新请求使用。
首先,你需要在项目中创建一个名为 cache.js 的新文件,你可以随意命名,如果项目有 services 目录,就把它放在 services 目录下;如果没有,就把它放在任何位置。
该文件将包含我们的服务器缓存数据和从 Redis 检索数据所需的所有逻辑。
首先,我们需要连接到 Redis 并确保它运行正常。
创建密钥:
为了在 Redis 中存储数据,我们需要为每个查询提供一个唯一且一致的键,以便在收到请求时能够检索到正确的查询。
基本上,对任何数据库的每次查询都有筛选器和选项,用于获取特定的文档或记录。
我们将利用这个东西,把这些过滤器转换成字符串。
JSON.stringfy({ {title : "story"} , {skip : 10} })
// our key = "{{"title" : "story" }, {"skip" : 10}}"
// everytime any client will request the data that can be fetched
// with this query, the server will repsonse with the cached data
现在我们有了每个需要在数据库中执行的查询的键,接下来我们将在 Redis 中搜索这个键,如果存在,则返回其值而不是执行查询,如果未找到,则在数据库中执行查询,并将查询结果连同其键一起存储在 Redis 中以供后续请求使用,然后将结果发送给用户。
// this line will add the data fetched from mongoDB to redis
client.set(key, JSON.stringify(result))
// always remember, Redis only store values as a string or numbers
包起来:
首先,你需要为每个查询创建一个唯一且一致的键。
其次,在 Redis 中搜索此键,如果找到,则返回其值作为结果;否则,执行查询并将结果存储在 Redis 中,最后将其发送给用户。
参考:
学习Node.js的最佳课程。
https://www.udemy.com/course/advanced-node-for-developers/?ranMID=39197&ranEAID=SAyYsTvLiGQ&ranSiteID=SAyYsTvLiGQ-EDfB120pgYcJlhkNSEBp4Q&LSNPUBID=SAyYsTvLiGQ&utm_source=aff-campaign&utm_medium=udemyads
如何在 Node.js 中使用 Redis 实现缓存 | DigitalOcean
Redis + Node.js:缓存入门 - RisingStack
使用 Redis 在 Node.js 中实现缓存
使用强大的 Redis 缓存机制加速您的 Node.js 应用程序
感谢阅读,如果您对 JavaScript 或本系列文章有任何疑问,请随时提出。我非常感谢您的任何反馈,这有助于我改进内容。
文章来源:https://dev.to/osam1010/advanced-nodejs-topics-caching-46a1










](/upload/10-bqye.png)


