Redis проблема с подключением
В настоящее время мы сталкиваемся с большим количеством ошибок Redis с сообщением
Невозможно подключиться: ошибка чтения при подключении, попытка следующего сервера
Мы запускаем Redis на FreeBSD, используя PHP Redis, и нам трудно воспроизвести ошибку в Ubuntu, так что это может быть подсказка. На github существует давняя проблема на эту тему.
В основном мы получаем сокет от операционной системы с вызовом connect(host, port, timeout)
в phpredis, но когда мы делаем select(db_index)
после этого мы получаем исключение. Может ли быть проблема с постоянством? Я предполагаю, что connect ничего не делает в фоновом режиме и select пытается получить доступ к соединению, которое фактически закрыто.
Мы не сталкиваемся с тайм-аутом. Мы попытались настроить TIME_WAIT безуспешно.
Любые другие идеи о том, откуда может возникнуть проблема? Каков наилучший способ отследить проблему? может быть dtrace?
Обновить
В настоящее время мы изучаем наши настройки BGSAVE. Интересно, что для создания форка для процесса, который регулярно записывает данные на диск (постоянство), может потребоваться полсекунды и больше, и, возможно, Redis не может ответить на connect()
запросы в течение этого времени.
1 ответ
Мы снизили уровень ошибок на 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 несколько других компаний столкнулись с той же ошибкой. Bump также использовал систему master/slave. Подчиненный не принимает соединения и находится там только для сохранения данных (см. Обсуждение хакерских новостей здесь)
Хулу говорит следующее: "Чтобы поддерживать постоянную производительность на осколках, мы отключили запись на диск во всех осколках, и у нас есть задание cron, которое выполняется каждый день в 4 часа утра, выполняя команду" BGSAVE "для каждого отдельного экземпляра". ( см. здесь)
Редактировать:
Оказывается, это было просто временное исправление. Нагрузка увеличилась, и мы вернулись к высоким показателям ошибок. Тем не менее я вполне уверен, что фоновая операция (например, разветвление или кратковременный фоновый процесс) вызывает ошибки, поскольку сообщения об ошибках всегда появляются в блоках.
Edit2:
Поскольку Redis является однопоточным, всегда следите за длительными операциями, потому что они блокируют все остальное. Примером является keys *
команда. Избегайте этого и используйте scan
вместо