Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Able to connect to redis but set/get times out

I'm trying to do a get() from my AWS Lambda (NodeJS) on ElastiCache Redis using node_redis client. I believe that I'm able to connect to redis but I'm getting Time out (Lambda 60 sec time out) when I'm trying to perform a get() operation.

I have also granted my AWS lambda Administrator access just to be certain that it's not a permissions issue. I'm hitting lambda by going to AWS console and clicking the Test button.

Here is my redisClient.js:

const util = require('util');
const redis = require('redis');

console.info('Start to connect to Redis Server');
const client = redis.createClient({
    host: process.env.ElastiCacheEndpoint,
    port: process.env.ElastiCachePort
});

client.get = util.promisify(client.get);
client.set = util.promisify(client.set);

client.on('ready',function() {
    console.log(" subs Redis is ready");  //Can see this output in logs
});

client.on('connect',function(){
    console.log('subs connected to redis'); //Can see this output in logs
})

exports.set = async function(key, value) {
    console.log("called set!");
    return await client.set(key, value);
}

exports.get = async function(key) {
    console.log("called get!"); //Can see this output in logs
    return await client.get(key);
}

Here's my index.js which calls the redisClient.js:

const redisclient = require("./redisClient");

exports.handler = async (event) => {
    const params = event.params
    const operation = event.operation;
    try {

        console.log("Checking RedisCache by calling client get") // Can see this output in logs
        const cachedVal = await redisclient.get('mykey');
        console.log("Checked RedisCache by calling client get") // This doesn't show up in logs.
        console.log(cachedVal);
        if (cachedVal) {
            return {
                statusCode: 200,
                body: JSON.stringify(cachedVal)
            }
        } else {
            const setCache = await redisclient.set('myKey','myVal');
            console.log(setCache);
            console.log("*******")
            let response = await makeCERequest(operation, params, event.account);
            console.log("CE Request returned");
            return response;

        }
    }
    catch (err) {
        return {
            statusCode: 500,
            body: err,
        };
    }
}        

This is the output (time out error message) that I get:

{
  "errorMessage": "2020-07-05T19:04:28.695Z 9951942c-f54a-4b18-9cc2-119eed65e9f1 Task timed out after 60.06 seconds"
}

I have tried using Bluebird (changing get to getAsync()) per this: https://github.com/UtkarshYeolekar/promisify-redis-client/blob/master/redis.js but still got the same behavior.

I also changed the port to use a random value (like 8088) that I'm using to create client (to see the behavior of connect event for a failed connection) - in this case I still see a Timed Out error response but I don't see the subs Redis is ready and subs connected to redis in my logs.

Can anyone please point me in the right direction? I don't seem to understand why I'm able to connect to redis but the get() request times out.

like image 681
Vimanyu Avatar asked Sep 07 '25 00:09

Vimanyu


1 Answers

I figured out the issue and posting here in case it helps anyone in future as the behavior wasn't very intuitive for me.

I had enabled AuthToken param while setting up my redis. I was passing the param to lambda with the environment variables but wasn't using it while sending the get()/set() requests. When I disabled the AuthToken requirement from redis configuration - Lambda was able to hit redis with get/set requests. More details on AuthToken can be found here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticache-replicationgroup.html#cfn-elasticache-replicationgroup-authtoken

like image 95
Vimanyu Avatar answered Sep 09 '25 06:09

Vimanyu