В настоящее время у нас возникает много ошибок 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
вместо