Aller au contenu
EuroVPSEuroVPS

Brancher PHP sur Valkey Sentinel, et prouver que le basculement fonctionne

Un cache répliqué n'aide que si PHP suit la promotion. Comment configurer Sentinel, connecter WordPress et Laravel, choisir une politique d'éviction, tester.

Par EuroVPS Engineering

5 min de lecture
Wiring PHP to Valkey Sentinel, and proving the failover works

Bien des sites font tourner un cache Redis ou Valkey répliqué et tombent quand même quand le primaire meurt, parce que l'application pointe vers une adresse fixe. Les réplicas sont là, Sentinel en promeut un, et PHP continue de frapper à la porte du serveur mort. Voici comment construire le cache pour que le basculement atteigne réellement l'application, et comment le prouver avant d'en avoir besoin.

Pourquoi le cache fait partie de votre disponibilité

Un cache objet stocke des résultats calculés : options, menus, sessions, résultats de requêtes, fragments rendus. Sur un site WordPress, Magento ou Laravel chargé, il absorbe la plus grande partie de la charge de lecture de la base de données. Perdez-le, et chaque requête retourne à la base d'un coup. La base n'a jamais été dimensionnée pour cela, donc le site rampe en quelques minutes. Une instance de cache unique est donc un point de défaillance unique, même si elle ne contient rien que vous ne puissiez reconstruire.

La forme : un primaire, deux réplicas, trois Sentinels

Faites tourner trois nœuds de cache sur trois hôtes distincts : un primaire et deux réplicas. À côté de chacun, un processus Sentinel. Les Sentinels surveillent le primaire, s'accordent entre eux quand il a disparu, promeuvent un réplica, et répondent à la question que chaque client a besoin de poser : où est le primaire maintenant ?

Sur chaque réplica :

replicaof <primary-address> 6379
masterauth <secret>
requirepass <secret>

Et sur chacun des trois Sentinels :

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

Le 2 de la ligne monitor est le quorum : deux Sentinels sur trois doivent s'accorder sur le fait que le primaire est hors service avant qu'un basculement ne démarre. C'est pourquoi ils sont trois, sur trois hôtes différents.

down-after-milliseconds est le compromis entre vitesse et prudence. Nous le gardons court. Un basculement inutile coûte quelques secondes de cache miss ; une longue attente avec un primaire mort coûte une base de données qui rampe.

L'étape que l'on saute : des clients qui interrogent Sentinel

Un client configuré avec l'adresse du primaire n'apprendra jamais une promotion. L'application doit se connecter à travers Sentinel, par nom de service, et demander le primaire courant.

Avec phpredis directement :

$sentinel = new RedisSentinel(['host' => '<sentinel-1>', 'port' => 26379]);
[$host, $port] = $sentinel->getMasterAddrByName('cache');
$redis = new Redis();
$redis->connect($host, (int) $port);
$redis->auth('<secret>');

Le code de production doit essayer chaque Sentinel à tour de rôle, puisque n'importe lequel peut se trouver sur l'hôte qui vient de tomber.

Pour WordPress, le drop-in Redis Object Cache, très répandu, prend en charge Sentinel nativement dans 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, via Predis, prend une liste de Sentinels et deux options dans config/database.php :

'redis' => [
    'client' => 'predis',
    'default' => [
        'tcp://<sentinel-1>:26379',
        'tcp://<sentinel-2>:26379',
        'tcp://<sentinel-3>:26379',
        'options' => ['replication' => 'sentinel', 'service' => 'cache'],
    ],
],

Avec cela en place, une promotion n'exige aucun changement de configuration et aucun redémarrage de PHP.

Mémoire : plafonnez-la et choisissez qui est évincé

Un cache qui grossit jusqu'à ce que le tueur OOM du noyau intervienne a échoué de la pire manière possible. Fixez maxmemory à une part fixe de la RAM du nœud, en laissant de la place pour les tampons de réplication et le fork utilisé pour la persistance, et choisissez délibérément une politique d'éviction :

  • allkeys-lru pour un cache pur. Quand la mémoire est pleine, la clé la moins récemment utilisée part, quelle qu'elle soit. C'est le bon choix pour les caches objet.
  • volatile-lru si l'instance contient aussi des clés sans expiration qui ne doivent jamais être évincées, comme des sessions. Seules les clés avec un TTL sont candidates.

Mieux encore, séparez les sessions du cache objet. Un déploiement qui vide le cache objet ne devrait jamais déconnecter tous les clients. Sur un cluster partagé, donnez à chaque site sa propre base logique au minimum ; donnez aux sites gros ou critiques leur propre instance, pour qu'un vidage ou une croissance incontrôlée des clés d'un site ne puisse pas vider les caches de ses voisins.

Prouvez-le : tuez le primaire exprès

Un basculement que vous n'avez pas observé est un espoir. Avant la remise, nous exécutons ceci avec l'application connectée et le trafic en cours :

# 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

(Avec Redis, les commandes sont les mêmes sous redis-cli.)

Notez trois choses : combien de temps avant que +switch-master n'apparaisse, combien de temps avant que les temps de page ne reviennent à la normale, et si une requête a échoué plutôt que simplement ralenti. Une construction saine promeut en quelques secondes, et PHP suit sans que personne n'y touche. Puis redémarrez l'ancien primaire et confirmez qu'il rejoint comme réplica du nouveau, et non comme second primaire.

Pour une répétition plus douce qui n'arrête aucun service, SENTINEL FAILOVER cache force une promotion à la demande. Utile pour tester le côté client ; moins utile pour tester la détection, qui est la partie qui compte lors d'une mauvaise nuit.

Votre liste de contrôle

  • Trois nœuds de cache et trois Sentinels sur trois hôtes distincts, quorum de deux.
  • Authentification activée, et le cache joignable uniquement depuis le niveau web qui l'utilise.
  • Chaque application connectée à travers Sentinel par nom de service, pas à une adresse fixe.
  • maxmemory fixé et une politique d'éviction choisie pour ce que l'instance contient.
  • Sessions séparées du cache objet ; gros sites isolés des petits.
  • Un test de basculement consigné avec l'application connectée, y compris la réintégration de l'ancien primaire.

Si vous souhaitez que nous câblions ou testions votre couche de cache, nous le faisons volontiers.

Parler à un ingénieur

Related (rows[1])

Voir aussi : Cache objet avec basculement automatique · Niveaux web à haute disponibilité, N+1 à chaque couche · Constructions de plateformes à haute disponibilité

Publié le 18 août 2026.

Toutes les notes de terrain