Top.Mail.Ru
OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Redis Sentinel на VDS: отказоустойчивый кэш и сессии PHP

Как построить высокодоступный Redis для кэша и PHP‑сессий с автоматическим переключением мастера: 3 узла, Sentinel, репликация, таймауты клиентов, блокировки сессий, UFW и тестирование отказов. Разбираем конфиги, тюнинг, обслуживание, мониторинг и частые ошибки.
Redis Sentinel на VDS: отказоустойчивый кэш и сессии PHP

Если у вас несколько веб‑серверов и PHP‑приложение опирается на Redis для кэша и хранения сессий, план аварийного переключения мастера перестаёт быть «хотелкой» и превращается в обязательный элемент архитектуры. Redis Sentinel решает эту задачу: наблюдает за мастером, голосует большинством, переводит одну из реплик в мастер и сообщает клиентам новые координаты. В этой статье разберём, как поднять отказоустойчивый кластер Redis+Sentinel на VDS, настроить PHP‑сессии и кэш с автоматическим failover, а также что учесть в продакшене.

Зачем здесь Sentinel и чем он отличается от кластера

Redis Sentinel обеспечивает высокую доступность одиночной «мастер‑реплика» топологии: у нас есть один мастер для записи и одна/две (или больше) реплики для чтения и горячего переключения. Sentinel сам не хранит данные, он только наблюдает и координирует. Это проще и дешевле, чем полноценный Redis Cluster с шардированием, и достаточно для задач кэша и PHP‑сессий, где нам важны:

  • быстрый автоматический failover мастера;
  • единая «логическая» точка подключения для клиентов через имя мастера;
  • минимальная потеря данных при сбоях за счёт репликации;
  • простая эксплуатация на обычных VDS.

Sentinel — про высокую доступность (HA), а не про масштабирование записи. Вертикально масштабируйте Redis или используйте шардирование только когда упираетесь в CPU/память одного узла.

Минимальная архитектура и требования

Базовый вариант для HA — три узла. Два узла запускают Redis (мастер и реплика) и Sentinel, третий узел запускает как минимум Sentinel (можно и Redis‑реплику). Три Sentinel нужны для кворума: многим клиентам хватает «2 из 3» для принятия решений о failover.

  • Узлы: 3 VDS (2 vCPU, 2–4 GB RAM для Redis с умеренными нагрузками; для чистого Sentinel хватает 1 GB).
  • Порты: Redis на 6379, Sentinel на 26379.
  • Сеть: приватная/локальная подсеть между узлами; внешние доступы к Redis закрываем.
  • Время: синхронизация NTP/Chrony обязательна — тайминги влияют на детекцию падений.
  • Версии: Redis 6/7. Для PHP‑сессий через Sentinel удобнее иметь свежий phpredis (5.3+).
FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Установка Redis и Sentinel

Пример для Debian/Ubuntu. Выполните на всех узлах (на тех, где будет только Sentinel, пакет redis-server можно опустить):

sudo apt update
sudo apt install redis-server redis-sentinel php-redis

Полезно включить оверкоммит памяти (уменьшает вероятность ошибок выделения памяти у Redis после форков):

sudo sysctl -w vm.overcommit_memory=1
echo "vm.overcommit_memory=1" | sudo tee /etc/sysctl.d/99-redis.conf

Базовая конфигурация Redis: безопасность и производительность

Пример конфига мастера /etc/redis/redis.conf с безопасным биндингом и паролем. Адаптируйте IP частной сети и пароль:

bind 10.0.0.10 127.0.0.1
port 6379
protected-mode yes
requirepass StrongRedisPass
masterauth StrongRedisPass
maxmemory 1gb
maxmemory-policy allkeys-lru
appendonly no
save ""
replica-read-only yes
tcp-keepalive 60
latency-monitor-threshold 100
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command SHUTDOWN ""

Если хотите переживать перезапуски без потери сессий/кэша — используйте appendonly yes, но учтите рост IO. Для типичного кэша бывает достаточно непостоянного хранения (AOF/RDB отключены), чтобы экономить диск и ускорить форки.

Пример реплики (предположим, IP мастера 10.0.0.10):

bind 10.0.0.11 127.0.0.1
port 6379
protected-mode yes
requirepass StrongRedisPass
masterauth StrongRedisPass
replicaof 10.0.0.10 6379
replica-read-only yes
maxmemory 1gb
maxmemory-policy allkeys-lru
appendonly no
save ""
tcp-keepalive 60

Запуск и автозапуск:

sudo systemctl enable --now redis-server

Настройка Sentinel

На каждом узле с Sentinel пропишите мониторинг мастера. Пример /etc/redis/sentinel.conf (мастер на 10.0.0.10:6379, кворум 2):

port 26379
bind 10.0.0.10 127.0.0.1
protected-mode yes
sentinel monitor mymaster 10.0.0.10 6379 2
sentinel auth-pass mymaster StrongRedisPass
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
# Если NAT: явно объявить внешний адрес/порт, который видят другие сентины/клиенты
# sentinel announce-ip 10.0.0.10
# sentinel announce-port 26379

На втором и третьем узлах меняйте bind на их адреса, а параметры sentinel monitor и пароль остаются те же. Запускаем Sentinel:

sudo systemctl enable --now redis-sentinel

Проверка статуса:

redis-cli -h 10.0.0.11 -p 26379 SENTINEL masters
redis-cli -h 10.0.0.11 -p 26379 SENTINEL slaves mymaster
redis-cli -h 10.0.0.12 -p 26379 SENTINEL get-master-addr-by-name mymaster

Кворум — это число сенитинов, которые должны подтвердить недоступность мастера. Но для failover нужен ещё и majority (большинство) доступных сенитинов. На трёх узлах настройка кворума 2 — стандарт.

Вывод redis-cli SENTINEL masters/slaves и смена мастера

Firewall и порты

Откройте порты только внутри приватной сети. Для UFW это может выглядеть так (адаптируйте подсеть):

sudo ufw allow from 10.0.0.0/24 to any port 6379 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 26379 proto tcp
sudo ufw deny 6379
sudo ufw deny 26379

Если Redis/Sentinel не должны слушать внешние интерфейсы, лишний раз убедитесь, что в конфиге указан корректный bind, а не 0.0.0.0.

Имитируем отказ и проверяем failover

1) Убедитесь, что Sentinel видит мастера и реплику:

redis-cli -h 10.0.0.11 -p 26379 SENTINEL masters
redis-cli -h 10.0.0.11 -p 26379 SENTINEL slaves mymaster

2) Остановите мастер:

sudo systemctl stop redis-server

3) Следите за логами Sentinel (на любом узле):

journalctl -u redis-sentinel -f

Через ~5 секунд (настройка down-after-milliseconds) Sentinels достигнут кворума, выберут лидера и переведут одну из реплик в мастер. Проверяем координаты нового мастера:

redis-cli -h 10.0.0.12 -p 26379 SENTINEL get-master-addr-by-name mymaster

Верните старый мастер в строй. Он поднимется как реплика нового мастера, если в конфиге есть masterauth.

PHP‑сессии через Redis Sentinel

Есть два пути: использовать встроенный сессионный handler расширения phpredis с поддержкой Sentinel, либо управлять подключением в приложении (например, через Predis). Для системных «бесшовных» сессий проще первый вариант. Если нужна базовая теория и альтернативы, посмотрите материал про подключение Redis к PHP‑сессиям и объектному кэшу.

Вариант 1: phpredis с session.save_path и Sentinel

Проверьте, что расширение загружено и достаточно новое:

php -i | grep -i phpredis

Пример настроек в php.ini или отдельном /etc/php/<версия>/mods-available/redis.ini:

session.save_handler = redis
session.save_path = "sentinel:mymaster?sentinel=10.0.0.11:26379&sentinel=10.0.0.12:26379&sentinel=10.0.0.13:26379&auth=StrongRedisPass&database=0&persistent=1&timeout=2&read_timeout=2&retry_interval=0"
redis.session.locking_enabled = 1
redis.session.lock_retries = 10
redis.session.lock_wait_time = 20000

Комментарии по параметрам:

  • sentinel:mymaster — логическое имя мастера, как в sentinel.conf.
  • timeout и read_timeout — небольшие таймауты, чтобы не повисать при сбоях.
  • retry_interval=0 — лучше упасть быстро, чем ждать долго; PHP‑FPM сам отдаст 5xx, а следующий запрос уже может уйти на новый мастер.
  • redis.session.locking_enabled — включает блокировки сессий, чтобы параллельные запросы не перетирали данные.
  • lock_wait_time в микросекундах, lock_retries — попытки; подберите под RPS.

После изменения перезапустите PHP‑FPM:

sudo systemctl reload php8.2-fpm

Проверьте создание сессий и отсутствие ошибок в логах PHP‑FPM.

Вариант 2: Predis с Sentinel для объектного кэша

Когда кэш подключается не через системные сессии, а приложением, удобен Predis. Пример:

require 'vendor/autoload.php';

$sentinels = [
    ['host' => '10.0.0.11', 'port' => 26379],
    ['host' => '10.0.0.12', 'port' => 26379],
    ['host' => '10.0.0.13', 'port' => 26379],
];

$client = new Predis\Client([
    'replication' => 'sentinel',
    'service' => 'mymaster',
    'parameters' => [
        'password' => 'StrongRedisPass',
        'database' => 0,
        'read_write_timeout' => 2
    ],
    'sentinels' => $sentinels
]);

$client->setex('foo', 60, 'bar');
echo $client->get('foo');

Предпочитайте установку с таймаутами и небольшими лимитами ожидания — так приложение переживает переключение мастера без длинных стопов.

Пример session.save_path с Sentinel в php.ini

Тюнинг для кэша и сессий

  • Политика вытеснения. Для кэша подойдёт allkeys-lru или volatile-lru. Для сессий безопаснее хранить с TTL и volatile-lru, чтобы не выкидывать ключи без TTL.
  • TTL. Ставьте явные TTL в приложении. Для сессий ориентируйтесь на lifetime из PHP.
  • Persistence. Для кэша часто можно отключить и AOF, и RDB. Для сессий решайте по требованиям: если перезапуск узла без потери авторизаций критичен — включайте AOF.
  • min-replicas-to-write. Чтобы уменьшить риск потери данных при сетевых разрывах, ограничьте запись, если активных реплик меньше минимума: min-replicas-to-write 1, min-replicas-max-lag 5.
  • slowlog и latency. Включите slowlog-log-slower-than на разумный порог (например, 5–10 мс) и мониторьте пики задержек.

Сетевые таймауты и поведение при сбоях

Failover — это секунды. Важно, чтобы стеки выше относились к временным ошибкам терпимо:

  • PHP‑FPM: корректные request_terminate_timeout и pm.max_children с запасом, чтобы во время переключения не спровоцировать лавину 502.
  • Клиентские таймауты: в session.save_path и клиентских библиотеках выставляйте маленькие connect/read таймауты (1–2 с) и быстрые ретраи.
  • Пулы соединений: после failover старые соединения к бывшему мастеру становятся невалидными. Современные клиенты переподключаются сами. Если пишете свою обёртку — добавьте детекцию READONLY и переподключение.

Надёжность Sentinel в продакшене

  • Независимость. Разносите Sentinels по разным узлам/зонам отказа. Не держите все три на одном сервере.
  • announce‑ip/announce‑port. Если узел за NAT или у него несколько интерфейсов, явно объявляйте адреса, по которым его увидят другие Sentinels и клиенты.
  • Кворум и majority. На трёх узлах ставьте кворум 2. На пяти — 3. Следите, чтобы при плановых работах оставалось большинство.
  • Автозапуск и рестарт. Убедитесь, что redis-sentinel включён в автозапуск, а в unit нет запрета на перезапуск.

Если вместе с Redis вы строите отказоустойчивость и для БД, обратите внимание на материал про управление топологией MySQL и промоут мастера.

Наблюдение и алёрты

Минимальный набор команд для диагностики:

# Куда указывает имя мастера
redis-cli -h 10.0.0.11 -p 26379 SENTINEL get-master-addr-by-name mymaster

# Список реплик
redis-cli -h 10.0.0.11 -p 26379 SENTINEL slaves mymaster

# Статус репликации на самом Redis
redis-cli -a StrongRedisPass INFO replication | egrep "role|connected_slaves|master_host|master_link_status"

# Принудительный failover (для тестов)
redis-cli -h 10.0.0.11 -p 26379 SENTINEL failover mymaster

Логируйте ключевые события Sentinel и Redis в агрегатор, ставьте оповещения на смену роли, потерю кворума, рост rejected_connections, used_memory и задержки.

Частые ошибки и как их избежать

  • Открытые порты в интернет. Redis и Sentinel слушают только приватные адреса. Публичные интерфейсы закрыты и в конфиге, и в firewall.
  • Один Sentinel. Это не HA. Минимум три. На «2 из 2» тоже уязвимы к сетевым разрывам и сплит‑брейну.
  • Нет masterauth. При возврате прежнего мастера он не сможет реплицироваться без пароля и останется одиночкой.
  • Большие таймауты клиентов. Долгие зависания при failover вместо быстрого фейла и повторной попытки.
  • Неправильный announce-ip. Sentinels не могут договориться, клиенты не находят мастер — проверьте адреса и маршруты.
  • Недостаточно RAM. Redis — in‑memory. Следите за запасом памяти под данные, репликацию (RDB/AOF), форки и буферы.

Чек‑лист перед продакшеном

  • Три узла с Sentinel, кворум 2, majority достигается при падении одного узла.
  • Пароли/ACL настроены, опасные команды переименованы, порты закрыты снаружи.
  • Репликация мастера работает, masterauth на месте.
  • Выбранная политика вытеснения и лимиты памяти соответствуют нагрузке.
  • PHP‑сессии используют sentinel:mymaster с короткими таймаутами и включённой блокировкой.
  • Failover проверен: принудительный и естественный (остановка мастера).
  • Логи и метрики собираются, алёрты настроены.

Итоги

Redis Sentinel — простой и надёжный способ получить HA для кэша и PHP‑сессий на VDS без усложнения инфраструктуры. Правильно подобранная топология из трёх узлов, аккуратная сеть и таймауты клиентов, плюс минимальный тюнинг Redis под ваш профиль — и переключение мастера станет для пользователей почти незаметным. Закладывайте регулярные проверки failover и наблюдение за метриками — такая связка переживёт плановые работы и внезапные сбои без простоя сайта.

Поделиться статьей

Вам будет интересно

SMTP для сайтов на виртуальном хостинге: PHPMailer и безошибочные DNS‑записи OpenAI Статья написана AI Fastfox

SMTP для сайтов на виртуальном хостинге: PHPMailer и безошибочные DNS‑записи

Почта с сайта часто теряется из‑за спама и неверной конфигурации. Разбираем практичный путь: перейти на SMTP, настроить PHPMailer, ...
Orchestrator для MySQL: визуализация топологии и ручной промоут без паники OpenAI Статья написана AI Fastfox

Orchestrator для MySQL: визуализация топологии и ручной промоут без паники

Практическое руководство по Orchestrator в MySQL: базовая конфигурация, визуализация topology, безопасный ручной промоут, учёт GTI ...
Приватность логов: анонимизация IP, ретеншн и маскировка URI OpenAI Статья написана AI Fastfox

Приватность логов: анонимизация IP, ретеншн и маскировка URI

Логи нужны для отладки и аудита, но в них часто утекают PII: IP, параметры URI, реферер. Разберём, как в Nginx анонимизировать IP ...