Назад | Перейти на главную страницу

Проблема с подключением Redis

В настоящее время у нас возникает много ошибок Redis с сообщением

Невозможно подключиться: ошибка чтения при подключении, попытка следующего сервера

Мы запускаем Redis на FreeBSD с использованием PHP Redis, и нам трудно воспроизвести ошибку в Ubuntu, так что это может быть подсказкой. Есть длительный проблема по этой теме на github.

В основном мы получаем сокет от операционной системы с вызовом connect(host, port, timeout) в phpredis, но когда мы делаем select(db_index) после этого мы получаем исключение. Может быть проблема с настойчивостью? Я предполагаю, что connect ничего не делает в фоновом режиме, и select пытается получить доступ к соединению, которое фактически закрыто.

У нас нет тайм-аута. Мы безуспешно пытались настроить TIME_WAIT.

Есть ли другие идеи о том, откуда может возникнуть проблема? Как лучше всего отследить проблему? может быть, dtrace?

Обновить

В настоящее время мы изучаем наши настройки BGSAVE. Интересно, что создание форка для процесса, который регулярно записывает данные на диск (постоянство), занимает полсекунды и более, и, возможно, redis не может ответить на connect() запросов в течение этого промежутка времени.

Мы снизили частоту ошибок на 90% с помощью следующих команда redis:

CONFIG SET save ""

Это отключает BGSAVE, который регулярно сохраняет все изменения базы данных на диске. Причина ошибок подключения, скорее всего, связана с блокировкой fork() операция основного процесса redis для запуска процесса BGSAVE.

Redis.conf говорит:

# Redis may block too long on the fsync() call. Note that there is no fix for
# this currently, as even performing fsync in a different thread will block
# our synchronous write(2) call.

Также посмотрите, как реализован механизм с простым fork() Вот. Мы думаем об использовании выделенного сервера Redis из нашего пула, который будет отвечать за операции BGSAVE, а остальные просто использовать для чтения / записи.

Из чата IRC кажется, что пара других компаний столкнулась с такой же ошибкой. Удар также использовала систему ведущий / ведомый. Подчиненное устройство не принимает соединения и существует только для сохранения данных (см. обсуждение hackernews здесь)

Hulu гласит следующее: «Чтобы поддерживать постоянную производительность на сегментах, мы отключили запись на диск для всех сегментов, и у нас есть задание cron, которое запускается в 4 часа ночи каждый день, выполняя скользящую команду« BGSAVE »для каждого отдельного экземпляра». (посмотреть здесь)

Редактировать:

Оказывается, это было временное исправление. Нагрузка увеличилась, и мы вернулись к высокому уровню ошибок. Тем не менее я вполне уверен, что фоновая операция (например, форк или краткосрочный фоновый процесс) вызывает ошибки, поскольку сообщения об ошибках всегда появляются в блоках.

Edit2:

Поскольку Redis является однопоточным, всегда следите за длительными операциями, потому что они блокируют все остальное. Примером может служить keys * команда. Избегайте этого и используйте scan вместо