【问题标题】:What's the default timeout of ioredis send command for any redis call任何redis调用的ioredis发送命令的默认超时是多少
【发布时间】:2019-08-18 18:48:11
【问题描述】:

我正在将 ioredis 与节点应用程序一起使用,由于集群中的一些问题,我开始得到:

集群重定向过多。最后一个错误:错误:连接已关闭。

因此,我所有的 redis 调用都失败了,并且在很长一段时间后(从 1 秒到 130 秒不等)。

ioredis 库是否有任何默认超时,用于在向 redis 服务器发送执行命令后断言调用?

向redis服务器发送命令的失败时间超过100秒,是因为集群故障导致redis的队列大小高吗?

示例代码:

this.getData = function(bucketName, userKey) {
  let cacheKey = cacheHelper.formCacheKey(userKey, bucketName);
  let serviceType = cacheHelper.getServiceType(bucketName, cacheConfig.service_config);
  let log_info = _.get(cacheConfig.service_config, 'logging_options.cache_info_level', true);
  let startTime = moment();
  let dataLength = null;
  return Promise.try(function(){
    validations([cacheKey], ['cache_key'], bucketName, serviceType, that.currentService);
    return cacheStore.get(serviceType, cacheKey);
  })
  .then(function(data) {
    dataLength = (data || '').length;
    return cacheHelper.uncompress(data);
  })
  .then(function(uncompressedData) {
    let endTime = moment();
    let responseTime = endTime.diff(startTime, 'miliseconds');
    if(!uncompressedData) {
      if(log_info) logger.consoleLog(bucketName, 'getData', 'miss', cacheKey, that.currentService,
        responseTime, dataLength);
    } else {
      if(log_info) logger.consoleLog(bucketName, 'getData', 'success', cacheKey, that.currentService,
        responseTime, dataLength);
    }
    return uncompressedData;
  })
  .catch(function(err) {
    let endTime = moment();
    let responseTime = endTime.diff(startTime, 'miliseconds');
    logger.error(bucketName, 'getData', err.message, userKey, that.currentService, responseTime);
    throw cacheResponse.error(err);
  });
};

这里 logger.error(bucketName, 'getData', err.message, userKey, that.currentService, responseTime);

开始给出 1061ms 到 109939ms 范围内的响应时间。

请提供一些意见。

【问题讨论】:

    标签: node.js timeout redis-cluster ioredis


    【解决方案1】:

    正如您从 ioredis issue 中看到的,没有每个命令的超时配置。

    正如链接评论中所建议的,您可以使用基于 Promise 的策略作为解决方法。顺便说一句,这与 ioredis-timeout plugin 使用的策略相同,将原始命令包装在 Promise.race() 方法中:

    //code from the ioredis-timeout lib
    return Promise.race([
          promiseDelay(ms, command, args),
          originCommand.apply(redis, args)
    ]);
    

    因此您可以使用插件或this nice race timeout technique 在redis 客户端之上添加超时功能。请记住,底层命令不会被中断。

    【讨论】:

    • 感谢@lifeisfoo,是的,这肯定是一个解决方案,正在寻找任何内置的超时选项(如果有的话)。除此之外,您能帮我解释一下为什么上面的代码无法阻止将整个应用程序关闭的级联效应吗?我已经为此做好了准备。是否禁用 enableOfflineQueue 正确策略以避免级联效应?并且还使用竞赛或断路器之类的解决方案添加超时策略?
    • @mohit3081989 您是否尝试过使用 enableOfflineQueue: false 选项?当连接断开时,您的命令现在是否立即退出?您是否检查了集群的所有可用选项? github.com/luin/ioredis#cluster 文档说:“您应该确保 retryDelayOnFailover * maxRedirections > cluster-node-timeout 以确保在故障转移期间没有命令会失败
    • 这就是计划,我将禁用离线队列,同时我将设置断路器以确保命令在合理的时间退出。顺便说一下,所有参数都是默认的,所以 retryDelayOnFailover 应该不是问题。默认情况下,离线队列已启用,因此将进行更改以禁用它。此外,我没有在整个库中找到 cluster-node-timeout 参数,所以要么是未记录的,要么是参数名称是别的东西。
    【解决方案2】:

    我遇到了类似的问题,我在这里详细描述过:How to configure Node Redis client to throw errors immediately, when connection has failed? [READ DETAILS]

    修复其实很简单,只需将enable_offline_queue 设置为false。这是使用 Node Redis 的,所以你必须找出 IORedis 的等价物。将此设置为 false,将使所有命令立即抛出异常,您可以在 catch 块中处理并继续,而不是等待超时。

    请记住,当enable_offline_queue 设置为 false 时,您在与服务器存在连接问题时发出的命令将永远不会被执行。

    【讨论】:

      猜你喜欢
      • 2018-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-12
      • 2023-03-24
      • 2018-05-24
      • 2019-06-28
      相关资源
      最近更新 更多