Search code examples
redisnode-redisioredis

Redis Cluster on AWS configuration on connect-redis and ioredis


I have a Redis Cluster configured on AWS (ElastiCache).

It has a configuration endpoint and 6 nodes (3 shards).

When reading the documentation of the npm module here, it says that you have to incorporate ioredis to get it to work for a Redis cluster.

I shared the configuration below which works for a single Redis node but not for a cluster

"use strict";

// Include modules
var express = require("express"),
    cookieParser = require("cookie-parser"),
    bodyParser = require("body-parser"),
    session = require("express-session"),
    RedisStore = require("connect-redis")(session),
    middleware = require("./routes/middleware"),

    app = express(),
    sessionNameOfApp = createAppSpecificSession(configNameOfApp),

//This works but only for a single node. It doesn't work for a Redis Cluster
function createAppSpecificSession(config) {
    return session({
        store: new RedisStore({
            host: config.SESSION.host,
            port: config.SESSION.port,
            pass: config.SESSION.pass
        }),
        resave: false,
        saveUninitialized: false,
        secret: config.SESSION.cookieSecret,
        name: config.SESSION.cookieName,
        genid: sessionMethods.generateSessionId
    });
}

app.use(middleware.setUUIDOnReq);
app.use(middleware.setAgentOnReq);

// additional app modules
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(cookieParser());

app.use(middleware.setSessionMethods);

// Include routes
require("./routes/app")(express, app);

module.exports = app;

My question is - how do I incorporate ioredis to support clustering?

This is a huge blocker for me so any help will be highly appreciated.

Looked for an example all over the net and got nothing!


Solution

  • This is what worked for me in the end:

    app.js file:

    "use strict";
    
    // Include modules
    var express = require("express"),
        path = require("path"),
        cookieParser = require("cookie-parser"),
        bodyParser = require("body-parser"),
        session = require("express-session"),
        RedisStore = require("connect-redis")(session),
        Redis = require('ioredis'),
        config = require("./config"),
        errorMessage = require("./errors/errorMessage"),
        sessionMethods = require("./utils/sessionMethods"),
        helmet = require("helmet"),
        middleware = require("./routes/middleware"),
        app = express(),
        session = createAppSpecificSession(config),
    
    function createAppSpecificSession(config) {
    
        var redis = null;
        redis = new Redis({
            host: config.SESSION.host,
            port: config.SESSION.port,
            password: config.SESSION.password
        });
    
        return session({
            store: new RedisStore({
                client: redis
            }),
            resave: false,
            saveUninitialized: false,
            secret: config.SESSION.cookieSecret,
            name: config.SESSION.cookieName,
            genid: sessionMethods.generateSessionId
        });
    }
    
    app.use(helmet());
    app.use(middleware.setUUIDOnReq);
    app.use(middleware.setAgentOnReq);
    
    // additional app modules
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
        extended: false
    }));
    app.use(cookieParser());
    
    app.use("/", session);
    
    // Include routes
    require("./routes/app")(express, app);
    
    module.exports = app;
    

    And the config file:

    config.js

    module.exports = {
        SESSION: {
            hosts: [{
                host: "endpoint1.0001.apse1.cache.amazonaws.com",
                port: 6379,
                password: "",
            }, {
                host: "endpoint2.0002.apse1.cache.amazonaws.com",
                port: 6379,
                password: "",
            }, {
                host: "endpoint3.0003.apse1.cache.amazonaws.com",
                port: 6379,
                password: "",
            }],
            cookieName: "connect.sid",
            cookieSecret: ["blablabla", "blablabla"]
        }
    };