Caching in NodeJs using Redis

30 / Apr / 2016 by Vibhor Kukreja 0 comments

Whenever we talk about nodejs development, the first thing that comes to our mind is managing concurrent requests in an efficient way. We can leverage our server performance and efficiency even more by providing a mechanism to cache it’s processed data(response) which seldomly changes. Such as products list, country codes, application configurations, etc.

In this blog, we will be using the Redis(an in-memory data store) to achieve caching in a node server. To begin with it, we will need redis to be installed on to our machine (link : http://redis.io/download).

After installing redis to your machine we can start the redis server.

redis

The default port of redis is 6379. For more details about redis you can refer to http://redis.io/.

Let us consider an example where we have to fetch list of products from a legacy application server, and the list of products seldomly changes. So we can easily cache these products list on our nodejs server. To do so, we need to require the redis module in our node application, which serves as a redis client to connect with the redis server.

var redis = require('redis');
var client = redis.createClient(6379, '127.0.0.1');

Now we can use this client to store and fetch the data from the cache(redis).

To store the value in redis:

client.set(<key>, JSON.stringify(<value>), function(error) { });

And to fetch value from redis:

client.get(<key>, function(error, value) { });

The below code demonstrates, how redis can be used with express framework(NodeJs)

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var request = require('request');

var redis = require('redis');
var client = redis.createClient(6379, '127.0.0.1');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: true
}));

app.get('/products/:id', function (req, res) {
        client.get(req.params.id, function(error, product) {
            if (error) {throw error;}
            if (product) {
                res.json(JSON.parse(product));
            } else {
              request({uri: '<some_other_domain>/products/' + req.params.id}, function(error, response, body) 							  {
                    if (error) {throw error;return}
                    if (!error && response.statusCode === 200) {
                        res.json(body);
                        client.set(req.params.id, JSON.stringify(body), function (error) {
                            if (error) {throw error;}
                        });
                    } else {
                        res.send(response.statusCode);
                    }
                });
            }
        });
    });

var server = app.listen(3000, function () {
    console.log('Server running at http://127.0.0.1:3000/');
});

The products API first try to check the data in the redis, before fetching it from “some_other_domain”. If the data is present in redis then, it will fetch it from the memory and respond back to the request. Else it will make a request to the “some_other_domain” and then store the response to redis before responding back to the request, so that it can be cached.

If you want to set an expiration time for the cache, you can do so by using the ‘setex’ method of redis module.

Syntax:

client.setex(<key>, <expirationTimeInSeconds>, JSON.stringify(<value>), function (error) { });

Similarly, we can also cache database result sets in redis, to enhance the performance of the APIs. By specifying expiration we can also take the advantage of refreshing our server cache as per the need of our application.

To demonstrate the API performance, I fetched 5000 records from a different server. It took around 19 seconds to respond without caching. And after caching the data on our node server, it just took around 110 millisecond to respond back.

Without Caching the response from our server:
without cache

Server response, after caching the request on Redis:
after cache

This difference is self explanatory, to understand the power of caching with redis.

Hope this will help. Happy coding.

FOUND THIS USEFUL? SHARE IT

Leave a comment -