Як під’єднати PHP до Valkey Sentinel і довести, що failover працює
Реплікований кеш допомагає лише тоді, коли PHP іде за promotion. Як налаштувати Sentinel, під’єднати WordPress і Laravel, обрати політику витіснення.

Чимало сайтів використовують реплікований кеш Redis або Valkey і все одно падають, коли гине primary, бо застосунок спрямований на одну фіксовану адресу. Репліки на місці, Sentinel підвищує одну з них, а PHP продовжує стукати у двері мертвого сервера. Ось як побудувати кеш так, щоб failover справді доходив до застосунку, і як довести це до того, як він вам знадобиться.
Чому кеш є частиною вашої доступності
Object cache зберігає обчислені результати: опції, меню, сесії, результати запитів, відрендерені фрагменти. На завантаженому сайті на WordPress, Magento або Laravel він поглинає більшу частину читального навантаження бази даних. Втратьте його, і кожен запит одразу повертається до бази даних. Базу даних ніколи не розраховували на це, тому сайт за лічені хвилини сповільнюється до повзання. Тож один інстанс кешу є єдиною точкою відмови, хоча й не містить нічого, чого не можна відбудувати.
Форма: один primary, дві репліки, три Sentinel
Запустіть три вузли кешу на трьох окремих хостах: один primary і дві репліки. Поруч із кожним запустіть процес Sentinel. Sentinel спостерігають за primary, домовляються між собою, коли його немає, підвищують репліку і відповідають на запитання, яке потрібне кожному клієнту: де зараз primary?
На кожній репліці:
replicaof <primary-address> 6379
masterauth <secret>
requirepass <secret>
І на кожному з трьох Sentinel:
sentinel monitor cache <primary-address> 6379 2
sentinel auth-pass cache <secret>
sentinel down-after-milliseconds cache 5000
sentinel failover-timeout cache 30000
sentinel parallel-syncs cache 1
2 у рядку monitor є кворумом: два з трьох Sentinel мають погодитися, що primary впав, перш ніж почнеться failover. Саме тому їх три, на трьох різних хостах.
down-after-milliseconds є компромісом між швидкістю та обережністю. Ми тримаємо його коротким. Непотрібний failover коштує кількох секунд промахів кешу; довге очікування з мертвим primary коштує бази даних, що повзе.
Крок, який пропускають: клієнти, що питають Sentinel
Клієнт, налаштований на адресу primary, ніколи не дізнається про promotion. Застосунок має з’єднуватися через Sentinel, за ім’ям сервісу, і питати про поточний primary.
З phpredis напряму:
$sentinel = new RedisSentinel(['host' => '<sentinel-1>', 'port' => 26379]);
[$host, $port] = $sentinel->getMasterAddrByName('cache');
$redis = new Redis();
$redis->connect($host, (int) $port);
$redis->auth('<secret>');
Робочий код має пробувати кожен Sentinel по черзі, бо будь-який з них може бути на хості, який щойно відмовив.
Для WordPress широко вживаний drop-in Redis Object Cache підтримує Sentinel нативно у wp-config.php:
define('WP_REDIS_CLIENT', 'phpredis');
define('WP_REDIS_SENTINEL', 'cache');
define('WP_REDIS_SERVERS', [
'tcp://<sentinel-1>:26379',
'tcp://<sentinel-2>:26379',
'tcp://<sentinel-3>:26379',
]);
define('WP_REDIS_PASSWORD', '<secret>');
Laravel, через Predis, приймає список Sentinel і дві опції у config/database.php:
'redis' => [
'client' => 'predis',
'default' => [
'tcp://<sentinel-1>:26379',
'tcp://<sentinel-2>:26379',
'tcp://<sentinel-3>:26379',
'options' => ['replication' => 'sentinel', 'service' => 'cache'],
],
],
Коли це на місці, promotion не потребує ні зміни конфігурації, ні перезапуску PHP.
Пам’ять: обмежте її і виберіть, кого витісняти
Кеш, який росте, доки не втрутиться OOM killer ядра, відмовив у найгірший можливий спосіб. Установіть maxmemory у фіксовану частку RAM вузла, залишивши місце для буферів реплікації та fork, який використовується для persistence, і свідомо оберіть політику витіснення:
allkeys-lruдля чистого кешу. Коли пам’ять заповнена, іде найдавніше використаний ключ, яким би він не був. Це правильно для object cache.volatile-lru, якщо інстанс також тримає ключі без терміну дії, які ніколи не можна витісняти, як-от сесії. Кандидатами є лише ключі з TTL.
Ще краще тримати сесії та object cache окремо. Деплой, який скидає object cache, ніколи не повинен розлогінювати кожного клієнта. У спільному кластері дайте кожному сайту щонайменше власну логічну базу даних; великим або критичним сайтам дайте власний інстанс, щоб скидання одного сайту або некероване зростання його ключів не могло спустошити кеші сусідів.
Доведіть: убийте primary навмисно
Failover, за яким ви не спостерігали, є надією. Перед передачею ми запускаємо це з під’єднаним застосунком і живим трафіком:
# 1. Who is primary right now?
valkey-cli -p 26379 SENTINEL get-master-addr-by-name cache
# 2. Watch the site from outside, timestamped
while true; do
printf '%s ' "$(date +%T.%N)"
curl -s -o /dev/null -w '%{http_code} %{time_total}\n' https://www.example.com/
sleep 0.5
done | tee cache-failover.log
# 3. On the primary's host, stop the cache service
systemctl stop valkey
# 4. Watch the Sentinel log for +switch-master, then ask again
valkey-cli -p 26379 SENTINEL get-master-addr-by-name cache
(З Redis команди ті самі під redis-cli.)
Запишіть три речі: скільки часу минуло до появи +switch-master, скільки до повернення таймінгів сторінок до норми і чи хоч один запит зазнав невдачі, а не просто сповільнився. Здорова збірка підвищує репліку за кілька секунд, і PHP іде за цим без чийогось втручання. Потім знову запустіть старий primary і підтвердьте, що він приєднується як репліка нового, а не як другий primary.
Для м’якшої репетиції, яка не зупиняє сервіс, SENTINEL FAILOVER cache примусово виконує promotion на вимогу. Корисно для тестування клієнтського боку; менш корисно для тестування виявлення, яке є тим, що має значення поганої ночі.
Ваш чекліст
- Три вузли кешу і три Sentinel на трьох окремих хостах, кворум два.
- Автентифікація ввімкнена, і кеш досяжний лише з вебрівня, який його використовує.
- Кожен застосунок з’єднується через Sentinel за ім’ям сервісу, а не з фіксованою адресою.
maxmemoryвстановлено і політику витіснення обрано під те, що тримає інстанс.- Сесії відокремлені від object cache; великі сайти ізольовані від малих.
- Записаний тест failover з під’єднаним застосунком, включно з поверненням старого primary.
Якщо ви хочете, щоб ми налаштували або протестували ваш рівень кешу, ми радо це зробимо.
Related (rows[1])
Пов’язане: Object caching з автоматичним failover · Вебрівні високої доступності, N+1 на кожному рівні · Побудова платформ високої доступності
Опубліковано 18 серпня 2026 р..
Усі нотатки з практики