Соединение Redis пропало из события закрытия

В нашей конфигурации Redis мы установили тайм-аут: 7 секунд

В node_redis мы обрабатываем готовое соединение redis и событие завершения как

client.on("ready", function() {
      logger.info("Connection Successfully Established to ", this.host, this.port);
}
client.on("end", function() {
    logger.fatal("Connection Terminated to ", this.host, this.port);
}

Образец журнала

[2012-07-11 08: 21: 29.545] [FATAL] Производство - Соединение прервано на конце с 'xxx9' '6399'
[2012-07-11 08: 21: 29.803] [ИНФОРМАЦИЯ] Производство - Соединение Успешно установлен на 'xxx9' '6399'

Но в некоторых случаях (скорее всего, redis закрывает соединение без уведомления клиента) мы видим очередь команд накапливается, и запросы требуют слишком много времени для получения ответа [до того момента, когда клиент node-redis не сможет определить событие закрытия]. Во всех таких случаях обратный вызов команды возвращается с этой ошибкой Redis connection gone from close event. даже после стольких ожиданий. Похоже, это не проблема из-за тайм-аута, поскольку обычное конечное событие не было запущено.

Проблема, похоже, похожа на эту - http://code.google.com/p/redis/issues/detail?id=368

Это известная вещь, которая происходит в Redis?

Есть ли способ указать, что выполнение команды [отправка и получение ответа] не должно превышать пороговое значение и в этом случае отвечать с ошибкой, вместо того, чтобы заставлять клиента останавливаться?

Или есть другой способ вызвать событие закрытия в таких случаях, как socket_timeout?

Или надо что-то проверить со стороны Redis? Мы наблюдали за нашим журналом redis на уровне debug и не нашли ничего полезного, связанного с этой проблемой.

Когда мы запускаем node-redis в режиме отладки, мы ясно видим, как клиент останавливается, а запросы накапливаются в очереди команд. Мы зарегистрировали почему и длину очереди внутри flush_on_error. Мы отключили offline_queuing.

Образец журнала

Соединение Redis пропало из события закрытия. автономная очередь 0 очередь команд 8

Время отклика на неудавшийся запрос: 30388 мс [это зависит от времени ожидания в очереди команд. Первый в очереди парень имеет максимальное время ответа, а следующие за ним меньше]

Обычное время отклика: 1 мс

PS: Мы также зарегистрировали проблему в node_redis


person Tamil    schedule 11.07.2012    source источник
comment
есть отзывы? вы не отметили правильный ответ   -  person oconnecp    schedule 08.01.2014


Ответы (2)


У нас также было несколько проблем с подключением к Redis. Похоже, он закроет соединение, не сообщая об этом клиенту. Мы заметили, что это, возможно, проблема с тайм-аутом на сервере. Это решение, которое мы используем, и у нас не было проблем с июля.

var RETRY_EVERY = 1000 * 60 * 3;
var startTimer = function(){
    console.log('Begin the hot tub!')
    setInterval(function(){
        try{
            client.set('hot',new Date());
            console.log(client.get('hot'))
        }
        catch(e){
            console.log(e);
        }

    },RETRY_EVERY)
}();

Учитывая, что это только один вызов каждые 3 минуты, это не должно быть проблемой для производительности;)

person oconnecp    schedule 20.12.2013
comment
Это решение очень очевидно, но мне было интересно, должен ли он быть клиентом, который сможет обнаружить соединение, закрытое из-за события тайм-аута, через какой-то протокол Redis и вызвать ошибку. Мы просто хотели знать, возможно ли что-нибудь в этом роде. - person Tamil; 10.01.2014
comment
Ваш клиентский код, который подключается к «концу», работает, и вы также можете подключиться к событию «ошибка» и обнаружить проблему, однако это внутренняя проблема либо в коде node-redis, либо в сервере redis. Без этого кода у вас будут проблемы с подключением, потому что в их коде есть ошибка. - person oconnecp; 10.01.2014

Что касается ответа oconnecp, не могли бы вы просто сделать:

setInterval(client.ping(), 1000 * 60 * 30);
person Vad    schedule 04.01.2014
comment
Гораздо более чистое решение. Спасибо - person Munim; 16.05.2014
comment
Разве это не должно быть setInterval(client.ping.bind(client), 1000 * 60 * 30); - person Madeline Trotter; 19.11.2014
comment
Похоже, node_redis 0.11.0 устранила проблему, установив по умолчанию socket_keepalive на true. Не уверен, почему это не всегда было по умолчанию, но неважно. - person Madeline Trotter; 19.11.2014