К основному содержимому

Сессии PHP в Redis для нескольких серверов

PHP · 29.09.2026

Зачем хранить сессии PHP в Redis на нескольких серверах

Стандартный обработчик сессий PHP пишет файлы в каталог /var/lib/php/sessions на локальном диске сервера. Пока приложение работает на одной машине, это не проблема. Как только за балансировщиком нагрузки появляются два и больше веб-сервера, пользователь при следующем запросе может попасть на другой сервер и потерять сессию: файл с её данными остался на первом хосте.

Решение — вынести хранилище сессий за пределы локального диска в общее хранилище, доступное всем серверам сразу. Redis подходит для этого лучше файловой системы NFS: он держит данные в памяти, отвечает за доли миллисекунды и поддерживает TTL из коробки, поэтому просроченные сессии удаляются сами. Настройка веб-серверов под Nginx и PHP-FPM, например по схеме из статьи Laravel на сервере с Nginx, обычно и приводит к необходимости общего хранилища сессий.

Как включить Redis как обработчик сессий

PHP умеет работать с Redis как с session.save_handler без дополнительного кода в приложении — достаточно двух директив в php.ini или в пуле PHP-FPM. Первая задаёт сам обработчик, вторая — адрес подключения.

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?timeout=2.5&persistent=1"

Параметр persistent=1 держит соединение с Redis открытым между запросами PHP-FPM и экономит время на установке TCP-соединения. Если Redis стоит на отдельном сервере, а не локально, замените 127.0.0.1 на его внутренний IP и обязательно закройте порт 6379 от внешнего мира правилами firewall.

Установка модуля php-redis и проверка

Директива session.save_handler = redis не заработает сама по себе — нужно расширение php-redis, собранное для установленной версии PHP.

apt install php-redis
systemctl restart php8.3-fpm
php -m | grep redis

Если сервер обслуживает несколько версий PHP одновременно, ставьте расширение под каждую версию отдельно — детали такой конфигурации разобраны в статье о нескольких версиях PHP на одном сервере. После установки перезапустите пул PHP-FPM, иначе воркеры будут работать со старым списком модулей ещё несколько часов.

Параметры session.save_path для Redis

Строка подключения поддерживает несколько параметров через амперсанд. Ниже — те, что реально пригождаются на проде.

ПараметрПримерНазначение
timeout2.5Таймаут подключения к Redis в секундах
persistent1Держать соединение между запросами
weight1Вес сервера при нескольких узлах Redis
prefixsess_Префикс ключей сессий в общей базе Redis

Префикс prefix стоит задавать всегда, если в той же базе Redis лежат ещё и данные кэша приложения: без него ключи сессий и кэша легко перепутать при чистке командой FLUSHDB.

Типичные ошибки при переносе сессий в Redis

  • Забыли перезапустить PHP-FPM после правки php.ini — старые воркеры продолжают писать сессии в файлы.
  • Redis настроен без пароля и слушает 0.0.0.0 — сессии всех пользователей доступны из интернета.
  • Не задан maxmemory-policy, из-за чего Redis при нехватке памяти начинает выселять ключи сессий как обычный кэш.
  • Session ID передаётся в URL вместо cookie — в логах и истории браузера остаётся чужая сессия.
  • Между серверами разное время (нет синхронизации NTP), из-за чего TTL сессии считается некорректно.

Итог: чек-лист переноса сессий в Redis

  • session.save_handler = redis и session.save_path указаны одинаково на всех веб-серверах.
  • Расширение php-redis установлено и подключено для каждой используемой версии PHP.
  • Redis защищён паролем requirepass и закрыт firewall от внешних подключений.
  • Задан maxmemory-policy noeviction или volatile-ttl для базы с сессиями.
  • После изменений выполнен перезапуск PHP-FPM и проверка через phpinfo, что сессии действительно пишутся в Redis.
← Назад в базу знаний Задать вопрос поддержке