Unable to connect to redis cluster with node client, what am I doing wrong?

0

I have spun up an AWS ElastiCache redis instance running in clustered mode, which currently has 1 shard and 2 nodes

In order to connect to it from my local machine I have opened up an SSH tunnel using my SSH config file

Host myRedisTunnel
  HostName 1.2.3.4
  ...
  LocalForward 6378 5.6.7.8:6379

the tunnel works, I can connect to my VPC successfully

$ ssh myRedisTunnel
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1060-aws x86_64)
...

I can connect to the redis cluster locally via redis-cli after opening my tunnel and passing -c as an argument for clustered mode

$ redis-cli -c -h localhost -p 6378
localhost:6378> ping
PONG

but when I try to use redis for nodejs it wont connect, it just times out, am i missing some configuration settings, or is it physically impossible to connect to my remote redis via tunnel?

const { createCluster } = require('redis')

const client = createCluster({
  rootNodes: [
    { url: 'redis://localhost:6378' }
  ]
})

await client.connect()
const res = await client.ping()
console.log({ res })
Error: Connection timeout
      at Socket.<anonymous> (node_modules/@node-redis/client/dist/lib/client/socket.js:163:124)
      at Object.onceWrapper (node:events:513:28)
      at Socket.emit (node:events:394:28)
      at Socket._onTimeout (node:net:486:8)
      at listOnTimeout (node:internal/timers:557:17)
      at processTimers (node:internal/timers:500:7)

I have tried several nodejs clients for redis and all of them have timed out in the same way, so I know the issue has to either be that I have a config setting wrong in my nodejs redis client configuration - or it has something to do with only one of the redis ip addresses is accessible via tunnel, all the rest of the cluster would likely not be accessible unless i open tunnels for each one. Im just at a loss for how mock my production environment in development so i can write code.

asked 2 years ago431 views
1 Answer
0

When connecting to Redis with cluster mode enabled, many clients will try to connect to all cluster nodes on initialization. The replica node(s) will not be reachable given the network setup that you have described. If you disable this behaviour of pre-connecting to all nodes, you should be able to successfully connect to the individual node that you have opened a tunnel onto.

Here is an example of how to connect without attempting to connect to all nodes, using the popular ioredis library:

let Redis = require('ioredis');

let cluster = new Redis.Cluster([{
  host: 'localhost',
  port: 6378
}], {
  lazyConnect: true
});

async function main() {
  await cluster.set("foo", "bar");
  console.log(await cluster.get("foo"));
  cluster.disconnect();
}
main();

NB: If more than one shard was setup in the cluster, this method would experience issues when hitting a shard on a different node to the node that you have tunnelled to.

AWS
answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions