微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js 和 redis 集群:处理断开连接

如何解决node.js 和 redis 集群:处理断开连接

TL;DR 将ioredis 与redis 集群一起使用,如果redis 无法访问,然后尝试重新连接,正确的获取错误方法是什么?

更多详情:

我正在使用 ioredis 从 node.js 连接到 redis 集群,并尝试为断开连接创建一个相当可靠的解决方案。我想要实现的一方面是在对 redis 的请求失败时收到错误,另一方面,尝试在后台和下一个请求中重新连接。 Ioredis 似乎没有很好地记录这一点,我能够实现这一点的唯一方法是组合 enableOfflineQueue=true添加一个返回 false 的 clusterRetryStrategy,并在捕获连接错误时,创建通过使用 new Redis.Cluster(...) 重新实例化 ioredis 的新连接。

请注意,我尝试过的其他配置都没有实现这种行为:要么永远重试而不抛出错误(如果 clusterRetryStrategy 未定义),要么立即抛出错误并且永远不会再次尝试重新连接(如果enableOfflineQueue 为假),无论我为 reconnectOnError 定义了什么。

  1. 我的主要问题是,这是一个好策略吗?我是否在之前的 Redis.Cluster 实例中留下了未清理的资源(即,这会造成内存泄漏)吗? 有没有更好的方法来实现这种行为(例如,明确告诉ioredis重新连接,而不重新实例化)?

  2. 一个问题,如果此技术实际上是推荐的策略,则是:似乎需要很长时间才能收到错误(针对本地集群运行 5-10 秒)-是否存在一种缩短连接错误的时间方法?有没有办法配置这个时间(比如~2 秒)?

为了清楚起见,下面是我用来测试的代码代码中真正相关的部分只是

if (redis.status === 'end') {
    redis = connectToCluster();
}

问题的真正含义是什么。

以下是我与 local redis cluster (on windows WSL) 结合运行的代码,我在测试运行时启动和停止该代码以观察行为。

const Promise = require('bluebird');
const Redis = require('ioredis');

function connectToCluster() {
    return new Redis.Cluster([
        { host: 'localhost',port: 30001 },{ host: 'localhost',port: 30002 },port: 30003 },port: 30004 },port: 30005 },port: 30006 },],{
        enableOfflineQueue: true,clusterRetryStrategy: times => false
    });
}

let redis = connectToCluster();

describe('Redis client: ',function () {
    it('should error when redis fails and return correct connection state when connected or not',async function () {
        this.timeout(300000);
        try {
            await wait(500);
            try {
                for (let i = 0; i < 100; i++) {
                    await redis.set(i,i);
                }
            } catch (e) {
                console.log(`======================================= Failed to insert test data =======================================`);
            }

            let succeeded = 0,Failed = 0;
            for (let i = 0; i < 300000; i++) {
                let start = Date.Now();
                try {
                    if (redis.status === 'end') {
                        console.log(`======================================= RECONNECTING TO CLUSTER (redis.status = "${redis.status}") =======================================`);
                        redis = connectToCluster();
                    }

                    await redis.get(i % 100);
                    succeeded++;
                } catch (e) {
                    console.log(`======================================= request ${i} Failed in ${Date.Now() - start}ms =======================================`);
                    Failed++;
                }

                if (i % 1000 === 0) {
                    console.log(`=============================== retrieved ${i} times,succeeded: ${succeeded},Failed: ${Failed} ===============================`);
                    global.gc();
                }
            }
        } catch (e) {
            console.log(`========== caught error: ${e.stack}`);
        }
    });
});

async function wait(ms = 10) {
    await Promise.resolve().delay(ms);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。