Desempenho e monitorização

Redis persistente para filas, sessões e Horizon

Revisto a 13 min de leitura redis colas sesiones laravel

O Redis Cache é uma cache: começa vazio sempre que é reiniciado e descarta chaves quando fica cheio. Serve para guardar o que a aplicação pode voltar a calcular, não uma fila de trabalhos pendentes nem a sessão de um utilizador. Para isso existe o Redis persistente: uma instância própria da sua conta que guarda os seus dados em disco e não os descarta quando fica cheia.

É o Valkey 8, compatível com Redis: funcionam os mesmos comandos e os mesmos clientes, como o PhpRedis. Está disponível nos planos Avanza, Max e Elastic.

Redis Cache ou Redis persistente

Redis Cache Redis persistente
Em todos os planos No Avanza, Max e Elastic
Para cache Para filas, sessões e Horizon
De 16 a 200 MB, consoante o plano De 64 a 512 MB, à sua escolha
Ao reiniciar, começa vazio Ao reiniciar, mantém os seus dados
Ao encher, descarta chaves Ao encher, rejeita escritas
Fora das cópias Nas cópias diárias

O Redis Cache liga-se por /tmp/redis.sock; o Redis persistente, por /home/USUARIO/.hostsuar/redis/redis.sock, com o seu utilizador do cPanel em vez de USUARIO. A memória do Redis Cache depende do plano; a do persistente é escolhida por si, até 128 MB no Avanza, 256 MB no Max e 512 MB no Elastic.

Pode usar os dois ao mesmo tempo: a cache no Redis Cache e as filas e sessões no Redis persistente. Explicamos como mais abaixo.

Em ambos os casos a porta é 0: ligam-se por socket, sem acesso pela rede. A aplicação tem de ser executada no próprio alojamento.

Ativá-lo

  1. Na área de cliente, abra Alojamento, entre no seu serviço e vá a Gestor de pacotes.
  2. No cartão Redis persistente, clique em Ativar.
  3. Reveja a memória, a persistência e o que fazer ao encher. Os valores predefinidos servem para filas, sessões e Horizon.
  4. Confirme e aguarde até que o painel o mostre em funcionamento.

O Redis persistente ocupa um dos processos persistentes do plano e aparece também em Ferramentas > Processos. Cada conta tem um; se todos os processos do seu plano já estiverem ocupados, elimine um antes de o ativar.

É executado com o utilizador da sua conta e dentro dos seus recursos. Só esse utilizador pode abrir o socket, por isso não precisa de palavra-passe.

Definições

Memória. 64 MB por predefinição, com um máximo de 128 MB no Avanza, 256 MB no Max e 512 MB no Elastic. Filas e sessões ocupam pouco: 64 MB chegam para a maioria das aplicações. Com o Horizon, a memória cresce com as métricas e os trabalhos recentes que guarda; ajustam-se em trim, dentro de config/horizon.php.

Persistência.

  • A cada segundo (predefinição): escreve cada alteração num ficheiro de registo (AOF) e passa-o para disco a cada segundo. Perante uma falha, perde-se, no máximo, o último segundo. É a que as filas e as sessões precisam.
  • Sem persistência: tudo vive em memória e um reinício deixa-o vazio. Use-a apenas se guardar dados que possa regenerar.

O que guarda em disco fica em ~/.hostsuar/redis/datos e conta para o espaço do seu plano, mesmo com o Redis parado. O cartão do Gestor de pacotes mostra quanto ocupa, junto da memória. Filas e sessões costumam ficar-se por poucos megas: o ficheiro de registo compacta-se sozinho quando cresce.

Ao encher.

  • Não perder dados (predefinição): quando chega ao limite, rejeita as escritas novas com um erro e não apaga nada. É a opção para filas, sessões e Horizon: a aplicação avisa do erro em vez de perder um trabalho sem que ninguém saiba.
  • Descartar o menos usado: apaga as chaves menos usadas para abrir espaço. Apenas para cache; com filas ou sessões perderia trabalhos e desligaria utilizadores.

Alterar as definições reinicia o Redis. Com A cada segundo recupera os seus dados ao voltar; se passar para Sem persistência, arranca vazio.

Ações

  • Definições: altera a memória, a persistência e o comportamento ao encher.
  • Reiniciar: para-o e arranca-o. Com persistência, mantém os dados.
  • Esvaziar: apaga tudo o que contém, em todas as suas bases: trabalhos pendentes das filas, sessões abertas (os utilizadores terão de voltar a entrar) e métricas do Horizon. Não pode ser anulado.
  • Desativar: para-o e retira-o, libertando assim o seu lugar de processo persistente. A aplicação perderá a ligação: altere antes o seu .env. O que estiver guardado fica na sua conta para o caso de o voltar a ativar, salvo se marcar Eliminar também o que tem guardado.

Pode verificar que responde a partir de SSH, com o seu utilizador em vez de USUARIO:

valkey-cli -s /home/USUARIO/.hostsuar/redis/redis.sock ping
valkey-cli -s /home/USUARIO/.hostsuar/redis/redis.sock info memory

O primeiro responde PONG; o segundo mostra a memória usada (used_memory_human) e o limite (maxmemory_human).

Ligá-lo a partir do Laravel

Ative a extensão redis (PhpRedis) na versão de PHP da aplicação e, se os seus workers usarem outra versão, também nessa. Depois, no .env:

REDIS_CLIENT=phpredis
REDIS_HOST=/home/USUARIO/.hostsuar/redis/redis.sock
REDIS_PORT=0
REDIS_PASSWORD=null

QUEUE_CONNECTION=redis
SESSION_DRIVER=redis

Substitua USUARIO pelo seu utilizador do cPanel. Com o Deploy+, edite o .env a partir do menu do repositório; se guardar a configuração em cache, volte a executar php artisan config:cache ou faça uma nova implementação. Verifique a ligação:

php artisan tinker --execute="dump(Illuminate\Support\Facades\Redis::connection()->ping());"

Deve mostrar true.

Antes de mudar de ligação, tenha em conta o que já existe:

  • Filas: os trabalhos que aguardam na base de dados não passam para o Redis. Deixe que a fila da base de dados se esvazie antes de alterar QUEUE_CONNECTION, ou mantenha durante algum tempo um worker sobre a ligação database.
  • Sessões: as sessões guardadas na base de dados não são transferidas. Ao alterar SESSION_DRIVER, os utilizadores terão de voltar a iniciar sessão.

Para processar as filas é preciso um worker em funcionamento: crie-o em Ferramentas > Processos como Worker de filas ou use o Horizon. Tem tudo em processos persistentes.

Com o Redis Cache ao mesmo tempo

Se quiser a cache no Redis Cache e o resto no Redis persistente, faça com que a ligação cache de config/database.php leia as suas próprias variáveis. Na ligação cache, altere o host e a porta:

'host' => env('REDIS_CACHE_HOST', env('REDIS_HOST', '127.0.0.1')),
'port' => env('REDIS_CACHE_PORT', env('REDIS_PORT', '6379')),

E no .env:

REDIS_HOST=/home/USUARIO/.hostsuar/redis/redis.sock
REDIS_PORT=0
REDIS_CACHE_HOST=/tmp/redis.sock
REDIS_CACHE_PORT=0
CACHE_STORE=redis

O armazenamento redis de config/cache.php usa a ligação cache para os dados e a default para os bloqueios, pelo que os bloqueios de Cache::lock() e withoutOverlapping() ficam no Redis persistente, que não os descarta.

Se tiver apenas o Redis persistente, deixe a cache na base de dados ou, se a puser no Redis, dê prazo de expiração ao que guardar: com Não perder dados, uma cache que cresce sem expirar acaba por encher a memória e bloquear também as filas.

Horizon

O Horizon precisa de filas no Redis e de um processo que o mantenha em funcionamento:

  1. Ative o Redis persistente e ligue o Laravel como na secção anterior, com QUEUE_CONNECTION=redis.
  2. Instale o Horizon no seu projeto com composer require laravel/horizon e php artisan horizon:install. Precisa das extensões pcntl e posix: se o Composer avisar que faltam, ative-as na versão de PHP que vai usar.
  3. Reveja config/horizon.php. O supervisor de production admite por predefinição até 10 workers, e cada um ocupa a sua memória dentro dos recursos da sua conta: ajuste maxProcesses ao que a sua aplicação precisa, por exemplo 2 ou 3 no Avanza.
  4. Decida quem pode ver o painel /horizon no método gate() de app/Providers/HorizonServiceProvider.php. Fora do ambiente local, só entra quem autorizar aí.
  5. Em Ferramentas > Processos, adicione um processo do tipo Horizon com a pasta da aplicação e a sua versão de PHP. Não crie também um worker de filas para as mesmas filas.
  6. Se publicar com o Deploy+, não acrescente nada ao script: depois de ativar cada versão, e também ao voltar a uma anterior, o processo Horizon dessa aplicação é reiniciado. O script corre antes de ativar a versão, por isso um horizon:terminate a partir daí faria o Horizon voltar a arrancar sobre a anterior. Se publicar de outra forma, execute php artisan horizon:terminate quando o código novo já estiver no seu lugar.
  7. Se quiser os gráficos de métricas, agende horizon:snapshot a cada cinco minutos em routes/console.php:
use Illuminate\Support\Facades\Schedule;

Schedule::command('horizon:snapshot')->everyFiveMinutes();

O Horizon com o Redis Cache não é seguro: se essa cache se esvaziar ou encher, perdem-se trabalhos pendentes.

Cópias de segurança

Os dados vivem na sua conta, em ~/.hostsuar/redis/, e entram nas cópias de segurança diárias como os restantes ficheiros.

Restaurar essa pasta devolve o Redis ao estado desse dia: os trabalhos que estavam pendentes nessa altura voltariam à fila, mesmo que já tivessem sido processados depois. Se precisar de a restaurar, pare antes o Redis persistente em Ferramentas > Processos e arranque-o quando a restauração terminar.

Também lhe pode ser útil

Algo não bate certo ou mudou? Diga-nos e revemos.