Saltar para o conteúdo
EuroVPSEuroVPS

Ligar o PHP ao Valkey Sentinel, e provar que o failover funciona

Uma cache replicada só ajuda se o PHP seguir a promoção. Como configurar o Sentinel, ligar WordPress e Laravel, escolher a eviction policy e testar tudo.

Por EuroVPS Engineering

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

Muitos websites correm uma cache Redis ou Valkey replicada e, mesmo assim, vão abaixo quando o primário morre, porque a aplicação aponta para um único endereço fixo. As réplicas estão lá, o Sentinel promove uma, e o PHP continua a bater à porta do servidor morto. Eis como construir a cache de modo que o failover chegue realmente à aplicação, e como o provar antes de precisar dele.

Porque é que a cache faz parte da sua disponibilidade

Uma object cache guarda resultados calculados: opções, menus, sessões, resultados de queries, fragmentos renderizados. Num website WordPress, Magento ou Laravel com movimento, absorve a maior parte da carga de leitura da base de dados. Perca-a, e todos os pedidos voltam à base de dados ao mesmo tempo. A base de dados nunca foi dimensionada para isso, por isso o website fica de rastos em poucos minutos. Uma única instância de cache é, portanto, um ponto único de falha, embora não guarde nada que não possa ser reconstruído.

A forma: um primário, duas réplicas, três Sentinels

Corra três nós de cache em três hosts separados: um primário e duas réplicas. Ao lado de cada um, corra um processo Sentinel. Os Sentinels vigiam o primário, acordam entre si quando ele desapareceu, promovem uma réplica e respondem à pergunta que todos os clientes precisam de ver respondida: onde está o primário agora?

Em cada réplica:

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

E em cada um dos três 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

O 2 na linha monitor é o quorum: dois dos três Sentinels têm de concordar que o primário está em baixo antes de começar um failover. É por isso que são três, em três hosts diferentes.

O down-after-milliseconds é o trade-off entre rapidez e cautela. Nós mantemo-lo curto. Um failover desnecessário custa alguns segundos de cache misses. Uma espera longa com um primário morto custa uma base de dados de rastos.

O passo que as pessoas saltam: clientes que perguntam ao Sentinel

Um cliente configurado com o endereço do primário nunca vai saber de uma promoção. A aplicação tem de se ligar através do Sentinel, pelo nome do serviço, e pedir o primário atual.

Com phpredis diretamente:

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

O código de produção deve tentar cada Sentinel por ordem, já que qualquer um deles pode estar no host que acabou de falhar.

Para WordPress, o drop-in Redis Object Cache, amplamente utilizado, suporta Sentinel nativamente no 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>');

O Laravel, através do Predis, recebe uma lista de Sentinels e duas opções no config/database.php:

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

Com isto no lugar, uma promoção não precisa de nenhuma alteração de configuração nem de nenhum restart do PHP.

Memória: ponha um limite e escolha quem sai

Uma cache que cresce até o OOM killer do kernel intervir falhou da pior forma possível. Defina o maxmemory como uma fração fixa da RAM do nó, deixando espaço para os buffers de replicação e para o fork usado na persistência, e escolha a eviction policy de forma deliberada:

  • allkeys-lru para uma cache pura. Quando a memória enche, sai a chave menos recentemente usada, seja ela qual for. É a escolha certa para object caches.
  • volatile-lru se a instância também guardar chaves sem expiração que nunca podem ser despejadas, como sessões. Só as chaves com TTL são candidatas.

Melhor ainda, mantenha as sessões e a object cache separadas. Um deploy que limpa a object cache nunca deve terminar a sessão de todos os clientes. Num cluster partilhado, dê a cada website, no mínimo, a sua própria base de dados lógica. Dê aos websites grandes ou críticos a sua própria instância, para que a limpeza ou o crescimento descontrolado de chaves de um website não possa esvaziar as caches dos vizinhos.

Prove-o: mate o primário de propósito

Um failover a que não assistiu é uma esperança. Antes da entrega, corremos isto com a aplicação ligada e tráfego a fluir:

# 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

(Com Redis, os comandos são os mesmos com redis-cli.)

Anote três coisas: quanto tempo até aparecer o +switch-master, quanto tempo até os tempos das páginas voltarem ao normal, e se algum pedido falhou em vez de apenas abrandar. Uma construção saudável promove em poucos segundos, e o PHP segue sem ninguém lhe tocar. Depois volte a arrancar o primário antigo e confirme que ele se reintegra como réplica do novo, não como segundo primário.

Para um ensaio mais suave que não pára nenhum serviço, o SENTINEL FAILOVER cache força uma promoção a pedido. Útil para testar o lado do cliente. Menos útil para testar a deteção, que é a parte que conta numa noite má.

A sua lista de verificação

  • Três nós de cache e três Sentinels em três hosts separados, quorum de dois.
  • Autenticação ativa, e a cache acessível apenas a partir da camada web que a utiliza.
  • Todas as aplicações a ligarem-se através do Sentinel pelo nome do serviço, não a um endereço fixo.
  • maxmemory definido e uma eviction policy escolhida para o que a instância guarda.
  • Sessões separadas da object cache. Websites grandes isolados dos pequenos.
  • Um teste de failover registado com a aplicação ligada, incluindo a reintegração do primário antigo.

Se quiser que montemos ou testemos a sua camada de cache, teremos todo o gosto.

Fale com um engenheiro

Related (rows[1])

Relacionados: Object caching com failover automático · Camadas web de alta disponibilidade, N+1 em cada nível · Construção de plataformas de alta disponibilidade

Publicado em 18 de agosto de 2026.

Todas as notas de campo