redisnode-redisioredis

ReplyError: MOVED error after connecting to Redis Cluster AWS


I am building a nodejs app that connects to redis. I have this working with my local instance of redis. Now, I am using ioredis to connect from my nodejs app to my redis cluster in k8s in AWS. Here is what I have.

const Redis = require("ioredis");

this.redis = new Redis({
 port: 6379, // Redis port
 host: rhost, // Redis host
 password: password
});

this.redis.on('connect', () => {
 console.log('connected to redis')
})

It seems like I successfully connect to my cluster as the message connected to redis prints out in the log. However, every time I try to use my redis object I get a MOVED error:

UnhandledPromiseRejectionWarning: ReplyError: MOVED 5011 <ip address>:6379
  at parseError (/node_modules/ioredis/node_modules/redis-parser/lib/parser.js:179:12)
  at parseType (/node_modules/ioredis/node_modules/redis-parser/lib/parser.js:302:14)

The connection works on my local. However, in AWS it does not. I tried swapping using the Redis.Cluster object instead of Redis, but after I deploy the app, the application hangs and the connection event never fires. The close and reconnecting events seem to be looping infinitely.

From my understanding, this is a problem with redirecting between nodes in the cluster. Perhaps it's a problem with the master/slave configuration. Is the error a configuration issue in AWS? Do I need to use the Redis.Cluster object instead of the plain Redis instance? What is the best way to fix the MOVED error?


Solution

  • The MOVED error is caused by using the Redis client directly and the configuration endpoint of ElastiCache (Redis Cluster Mode). This can be solved by using new Redis.Cluster([{ host: <cfg-endpoint>]) which is aware about multiple shards.

    Otherwise disable the Redis Cluster Mode and use the primary (master) dns name of your ElastiCache cluster. Even without Redis Cluster Mode there is still a Failover Strategy (AWS will replace primary node when it fails) and you can deploy Nodes into multiple Availablity Zones.

    Also when you have Encryption enabled you will need to connect to AWS ElastiCache with TLS enabled (tls: {} option for ioredis).

    https://aws.amazon.com/blogs/database/work-with-cluster-mode-on-amazon-elasticache-for-redis/