redis / ioredis

🚀 A robust, performance-focused, and full-featured Redis client for Node.js.
MIT License
14.26k stars 1.19k forks source link

Looping on ERR max number of clients reached #1348

Open PaddyOl opened 3 years ago

PaddyOl commented 3 years ago

Using version ioredis@4.27.2 (but problems also in older version, can't say since when):

Error: Command queue state error. If you can reproduce this, please report it. Last error: ERR max number of clients reached at DataHandler.shiftCommand (/myApp/node_modules/ioredis/built/DataHandler.js:164:27) at DataHandler.returnError (/myApp/node_modules/ioredis/built/DataHandler.js:33:27) at JavascriptRedisParser.returnError (/myApp/node_modules/ioredis/built/DataHandler.js:15:22) at JavascriptRedisParser.execute (/myApp/node_modules/redis-parser/lib/parser.js:542:14) at Socket. (/myApp/node_modules/ioredis/built/DataHandler.js:25:20) at Socket.emit (events.js:314:20) at addChunk (_stream_readable.js:297:12) at readableAddChunk (_stream_readable.js:272:9) at Socket.Readable.push (_stream_readable.js:213:10) at TCP.onStreamRead (internal/stream_base_commons.js:188:23) at TCP.callbackTrampoline (internal/async_hooks.js:126:14)

loops ...

my config of redis client: { sentinels:[ {host : '1.1.1.1', port : 26379 }, {host : '2.2.2.2', port : 26379 }, {host : '3.3.3.3', port : 26379 }, ], name: 'mymaster', options: { enableOfflineQueue: false, password: '***', connect_timeout: 10000 }, }

Can't see in my logs what has triggered this activity ...

luin commented 3 years ago

Hi @PaddyOl, can you run client list with redis-cli when similar errors happen?

keshav-gaur commented 2 years ago

@luin I'm also facing the similar issue and I checked the client list those were all from my production servers

luin commented 2 years ago

@luin I'm also facing the similar issue and I checked the client list those were all from my production servers

Thanks for reporting this. I think you may want to increase the client limit as the error happens when there are too many clients. However, seems ioredis should handle this to avoid the command queue error.

keshav-gaur commented 2 years ago

@luin I have increased the limit already and has set that to 25000 but still I reach a point where number of clients reach the threshold.

luin commented 2 years ago

@luin I have increased the limit already and has set that to 25000

but still I reach a point where number of clients reach the threshold.

Sounds like there should be some usage issues? A typical web application would only have 1 connection per Node.js process so I think you need to find the cause why there are so many connections.

keshav-gaur commented 2 years ago

@luin I have created a singleton class which returns only one client and I use that to call redis functions, Do I explicitly have to quit the client connection?

luin commented 2 years ago

@luin I have created a singleton class which returns only one client and I use that to call redis functions,

Do I explicitly have to quit the client connection?

It's pretty related to your project's specific setup. Generally you don't need to quit explicitly. You may want to refer to the express example in the example folder of this repo. Also, printing a log in your singleton class may help you debug whether the singleton works or not.

keshav-gaur commented 2 years ago

@luin I went through the example and I'm using redis in the similar manner. I have checked that singleton is working fine. the version which I'm using is "ioredis": "^4.14.0",

let redisIoSingletonClient = null

const getIoRedisClient = async () => new Promise((resolve, reject) => {
        if (redisIoSingletonClient) {
            return resolve(redisIoSingletonClient);
        }
        redisIoSingletonClient = new IoRedis(redisConfig);

        redisIoSingletonClient.on('error', (err) => {
            redisIoSingletonClient = null;
            console.error('Error in connecting to getIoRedisClient', { stack: err });
            logger.error(err, FILE_NAME, 'getIoRedisClient', ERROR_OBJ.GETIOREDISCLIENT);
            return reject(err);
        });
        redisIoSingletonClient.on('connect', async () => resolve(redisIoSingletonClient));
});

module.exports = {
    getIoRedisClient,
};

image

Please help me understand what am I doing wrong? @luin

luin commented 2 years ago

@keshav-gaur Nothing comes to my mind. The code looks correct so I assume there should be somewhere else that also creates Redis connections. You can try to assign the connection a name to debug this.

keshav-gaur commented 2 years ago

okay @luin thanks, I will check this possibility also.