Reputation: 523
I'm dealing with a ClusterAllFailedError: Failed to refresh slots cache.
issue from ioredis and Elasticache. This is my clustering config
const clusterOptions = {
enableReadyCheck: true,
retryDelayOnClusterDown: 300,
retryDelayOnFailover: 1000,
retryDelayOnTryAgain: 3000,
slotsRefreshTimeout: 200000000000000,
clusterRetryStrategy: (times) => Math.min(times * 1000, 10000),
dnsLookup: (address, callback) => callback(null, address),
scaleReads: 'slave',
showFriendlyErrorStack: true,
redisOptions: {
keyPrefix: config.queue.prefix,
autoResubscribe: true,
autoResendUnfulfilledCommands: true
}
}
const redisClientInstance = new Redis.Cluster([{ host: '', port: ''}], clusterOptions);
But trying to access the Redis always results in a Failed refresh slots cache
. Anyone else dealt with this issue?
Thank you.
Upvotes: 19
Views: 35662
Reputation: 804
In my case, it seems the slotsRefreshTimeout
was the problem. Included the option to increase the timeout and the error is not showing anymore. Here is my connection example:
let client = new Cluster([
{ port: 6379, host: <END_POINT> }
],{
dnsLookup: (address, callback) => callback(null, address),
slotsRefreshTimeout: 2000,
redisOptions: { tls: true }
});
Upvotes: 1
Reputation: 75
I recommend setting your client to debug mode
For ioredis you can do it like so:
DEBUG=ioredis:* node app.js
There might be an error you're not seeing
In my case there was Error: getaddrinfo ENOTFOUND
printed before the Failed to refresh slots cache
error was thrown
Upvotes: 3
Reputation: 13
Before trying any solution here, once verify that you are creating cluster with cluster mode enabled, this thing worked for me!
Here's an attached screenshot.
Upvotes: 0
Reputation: 6133
The following works for me.
Redis version: 5.0.4 on AWS ElastiCache
Clustered with TLS
and AUTH
enabled.
ioredis version: 4.16.0
Code to connect:
const redis = new Redis.Cluster(
[{ "host": <ELASTI_CACHE_CONFIGURATION_ENDPOINT> }], {
dnsLookup: (address, callback) => callback(null, address),
redisOptions: {
tls: true,
password: <ELASTI_CACHE_REDIS_AUTH>
}
});
When you launch ElastiCache
, you will need to specify one or more Subnet Group
(generally private Subnets) and the Security Group
. When you run the above code from any compute (Lambda, EC2 etc.), you need to ensure the following
ElastiCache
is reachable from your Compute (Put the compute in a Subnet which can communicate with the Subnet of the ElastiCache
in the same VPC
. If the compute and Elasticache
are on different VPCs, ensure VPC peering enabled between them.)Security Group
, NACL
allows the connection to ElastiCache
port (6379
is the default) from your Compute Subnet
IAM Role
(EC2 instance profile, Lambda Role etc) which has appropriate access to ElastiCache
. In case you are running on an EC2 instance, make sure your code uses the temporary credentials of the Role assigned in the EC2 instance profile.Upvotes: 15
Reputation: 31
This works for me but with small hack as i am using it in typescript, faced issue while passing null to first argument for callback function which expecting NodeJS.ErrnoException
and does't want to allow using any type(due to eslint no-explicit-any
rule).
I used @ts-expect-error directive above dnsLookup
// @ts-expect-error this will ignore error
dnsLookup: (address, callback) => callback(null, address),
Upvotes: 0