Redis + Node.js缓存使用简介

  理解和运用缓存是编写代码一个非常重要的方面,因此本文将解释什么是缓存,会帮助你如何开始使用Redis的+ Node.js

什么是缓存?

数据输入输出作为 一个简单的概念,已经存在了相当一段时间,但根据本Node.js的调查显示 ,许多开发者并不好好利用这个优势。

  • 开发人员认为缓存会使他们的应用程序更复杂
  • 有些事情在开始就没有规划实现

通过本文介绍,我们将看到:

  1. 缓存可以轻松地集成到您的应用程序中。
  2. 它不需要添加到任何地方,你可以只用一个资源开始进行试验。
  3. 即使最简单的实现也可以对性能产生积极影响。

与第三方API集成

要显示缓存的好处,我创建了一个Express应用程序,与GitHub的公共API集成,检索一个组织的公共仓库。

const express = require('express');
const request = require('superagent');
const PORT = process.env.PORT;

const app = express();

function respond(org, numberOfRepos) {
return `Organization "${org}" has ${numberOfRepos} public repositories.`;
}

function getNumberOfRepos(req, res, next) {
const org = req.query.org;
request.get(`https://api.github.com/orgs/${org}/repos`, function (err, response) {
if (err) throw err;

// response.body contains an array of public repositories
var repoNumber = response.body.length;
res.send(respond(org, repoNumber));
});
};

app.get('/repos', getNumberOfRepos);

app.listen(PORT, function () {
console.log('app listening on port', PORT);
});

启动应用程序,从浏览器http://localhost:3000/repos?org=risingstack发出几个请求 

从GitHub接收响应并通过我们的应用程序返回,整个过程花了一点时间,大概超过半秒。

当涉及与第三方API的通信时,我们自然地依赖于它们的可靠性。 错误将发生在网络以及其基础设施上。 应用程序重载,DOS攻击,网络故障,除了请求限制和限制 的专有API。

缓存如何帮助我们缓解这些问题?

我们可以暂时保存第一个响应,稍后再提供,而不会发生实际GitHub请求 这将导致较不频繁的请求,因此发生上述任何错误的机会较少。

你可能认为:我们会提供不一定准确的旧数据,但是想想数据本身:

存储库的列表是否会频繁更改? 可能不是,但一段时间后,我们可以再次询问GitHub最新的数据和更新我们的缓存。

Redis + Node.js:在我们的应用程序中使用Redis作为缓存

Redis可以在许多方面使用,但在本教程中把它作为一个key-value(散列映射或字典)数据库服务器。

我们将使用Redis Node.js的客户端与我们的Redis服务器进行通信。

要安装Redis的服务器本身,请参见官方的快速入门指南 。

从现在开始,我们假设你已经安装它,它已经正在运行。

让我们从将redis客户端添加到我们的依赖项开始:

 npm install redis --save 
      

然后创建与本地Redis服务器的连接:

const express = require('express');
const request = require('superagent');
const PORT = process.env.PORT;

const redis = require('redis');
const REDIS_PORT = process.env.REDIS_PORT;

const app = express();
const client = redis.createClient(REDIS_PORT);

 

缓存数据

正如前面已经指出的,Redis可以像哈希映射一样简单。只要向其中添加数据,使用:

 client.set('some key', 'some value'); 
      

如果你想让'一些键key“一段时间后失效 :

 client.setex('some key', 3600, 'some value'); 
      

此工作原理类似于set,在上面的例子中, some key将被在Redis中的一小时后去除。

下面是使用setex一个案例。

 var repoNumber = response.body.length;  
// for this tutorial we set expiry to 5s but it could be much higher
client.setex(org, 5, repoNumber);
res.send(respond(org, repoNumber));

对于这个演示,我们使用组织名称作为键,但根据您的用例,您可能需要一个更复杂的算法来生成它们。

检索高速缓存的数据

我们不是在app.get回调中实施缓存逻辑,要充分利用express中间件功能,所以导致实现可以在其他资源中很容易地被重复使用。

首先向现有处理程序添加中间件函数:

 app.get('/repos', cache, getNumberOfRepos); 
      

cache可以访问相同的请求对象( req ),响应对象( res ),以及在应用程序的请求-响应周期中的下一个中间件的函数类似getNumberOfRepos一样。

我们将使用此函数来拦截请求,提取组织的名称,看看我们是否可以从Redis提供任何内容:

function cache(req, res, next) {
const org = req.query.org;
client.get(org, function (err, data) {
if (err) throw err;

if (data != null) {
res.send(respond(org, data));
} else {
next();
}
});
}

  

我们使用get检索数据的Redis:

 client.get(key, function (err, data) { }); 
      

如果在缓存中没有指定的键,只是要简单调用next()进入下一个中间件函数: getNumberOfRepos 。

 

这个应用程序的初始实现花了2318毫秒来服务4个请求。使用缓存技术将此数字减少到672ms,服务相同的响应速度提高了71%或更快。我们向GitHub API发出了一个请求,而不是四个请求,减少了GitHub的负载,并减少了其他通信错误的几率。在第五个请求期间,缓存的值已过期。 我们再次击中GitHub(618ms)并缓存新的响应。 

 

NodeJs主题