Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Cluster mode documentation, especially in AWS ElastiCache with TLS #1816

Closed
rarecrumb opened this issue Sep 12, 2023 · 4 comments
Closed

Comments

@rarecrumb
Copy link

rarecrumb commented Sep 12, 2023

It seems very common to have issues connecting to AWS ElastiCache in Cluster mode, with TLS enabled.

@luin can you provide examples showing how to use ioredis to connect to Redis Cluster? Extra helpful if it can actually be tested against AWS ElastiCache in Cluster mode with TLS enabled/disabled, password auth enabled/disabled.

ioredis version: v5.3.2
Redis Cluster Engine version: 7.0.7 - TLS Enabled, no password

  static async createCluster(
    connectionString: ClusterNode[],
    ioRedisClusterOpts?: ClusterOptions
  ): Promise<RedisClient> {
    const opts: ClusterOptions = {
      ...ioRedisClusterOpts,
      clusterRetryStrategy() {
        const delay = Math.min(10 * 50, 2000);
        return delay;
      },
      scaleReads: "slave",
      lazyConnect: true,
      slotsRefreshInterval: 3000,
      slotsRefreshTimeout: 10000,
      enableOfflineQueue: false,
      dnsLookup: (address, callback) => callback(null, address),
      enableReadyCheck: true,
      redisOptions: {
        family: 6,
        tls: {},
      },
    };

    const client = new IORedis.Cluster(connectionString, opts);

    await client.connect();
    return new RedisClient(client);

Errors:

2023-09-12T20:22:37.357Z ioredis:connection error: Error: getaddrinfo ENOTFOUND x.us-east-1-xxx-xxx.xxx.use1.cache.amazonaws.com    
  at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:108:26)    
  at GetAddrInfoReqWrap.callbackTrampoline (node:internal/async_hooks:130:17) 
{  errno: -3007,  code: 'ENOTFOUND',  syscall: 'getaddrinfo',  hostname: 'xxx.us-east-1-xxx-xxx.xxx.use1.cache.amazonaws.com'}

Related issues:

@rarecrumb
Copy link
Author

rarecrumb commented Sep 13, 2023

These are the options that finally ended up working for me with ElastiCache with Cluster mode and TLS enabled:

      clusterRetryStrategy() {
        const delay = Math.min(10 * 50, 2000);
        return delay;
      },
      scaleReads: 'slave',
      lazyConnect: true,
      slotsRefreshInterval: 60000,
      slotsRefreshTimeout: 10000,
      enableOfflineQueue: true,
      enableReadyCheck: true,
      redisOptions: {
        tls:
          process.env.NODE_ENV === "production"
            ? {
                checkServerIdentity: (/*host, cert*/) => {
                  // skip certificate hostname validation
                  return undefined;
                },
              }
            : undefined,
        commandTimeout: 5000,
        connectTimeout: 10000,
        lazyConnect: true,
        enableReadyCheck: true,
        enableAutoPipelining: true,
        enableOfflineQueue: true,
        noDelay: true,
        keepAlive: 1000
      }

@nrathi
Copy link

nrathi commented Oct 24, 2023

@ rarecrumb how do you connect to the cluster when developing locally? I'm trying to tunnel via SSH but not sure if that's messing things up.

@blshukla
Copy link

We were facing a similar issue. This answer from Stack Overflow worked well for us - https://stackoverflow.com/questions/76409668/how-to-connect-to-amazon-memorydb-for-redis-from-node-running-in-ec2-ecs

@sonthanhdan
Copy link

These are the options that finally ended up working for me with ElastiCache with Cluster mode and TLS enabled:

      clusterRetryStrategy() {
        const delay = Math.min(10 * 50, 2000);
        return delay;
      },
      scaleReads: 'slave',
      lazyConnect: true,
      slotsRefreshInterval: 60000,
      slotsRefreshTimeout: 10000,
      enableOfflineQueue: true,
      enableReadyCheck: true,
      redisOptions: {
        tls:
          process.env.NODE_ENV === "production"
            ? {
                checkServerIdentity: (/*host, cert*/) => {
                  // skip certificate hostname validation
                  return undefined;
                },
              }
            : undefined,
        commandTimeout: 5000,
        connectTimeout: 10000,
        lazyConnect: true,
        enableReadyCheck: true,
        enableAutoPipelining: true,
        enableOfflineQueue: true,
        noDelay: true,
        keepAlive: 1000
      }

thanks @rarecrumb I tried with your config it working fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants