English | العربية | বাংলা | Bosanski | Deutsch | Español | Français | हिन्दी | Italiano | 日本語 | 한국어 | मराठी | Português | Русский | Kiswahili | தமிழ் | తెలుగు | Türkçe | اردو | Tiếng Việt | 中文
- Introdução
- Instalação
- Uso
- Configuração
- Uso Avançado
- Otimização
- Padrões Comuns
- Limitações
- Diretrizes de Suporte
- Licença - Licença MIT
Introdução
Recall é um pacote de caching de alto desempenho do lado do cliente Redis para Laravel. Ele utiliza o recurso de caching do lado do cliente do Redis 6 com invalidação automática para reduzir drasticamente as idas e voltas ao Redis e a latência. Desenvolvido especificamente para ambientes Laravel Octane, ele usa APCu ou Swoole Table como uma camada de cache local que permanece sincronizada com o Redis por meio de mensagens de invalidação.
Quando você busca um valor do Redis, o Recall armazena-o localmente. Quando esse valor muda no Redis (de qualquer cliente), o Redis notifica automaticamente o Recall para invalidar a cópia local. Isso proporciona a velocidade do caching em memória com as garantias de consistência do Redis.
Principais Características
- Invalidação Automática: O Redis notifica sua aplicação quando as chaves em cache mudam, garantindo a coerência do cache.
- Zero Configuração: Funciona imediatamente com padrões sensatos.
- Integração com Octane: Aquecimento automático de conexão, processamento de invalidação baseado em requisições e encerramento gracioso.
- Suporte a Drivers Duplos: APCu para todos os servidores Octane, Swoole Table para ambientes Swoole/OpenSwoole.
- Caching Seletivo: Configure quais prefixos de chaves devem ser armazenados localmente.
- Proteção contra Condições de Corrida: O rastreamento de requisições pendentes evita o armazenamento de dados obsoletos durante invalidações concorrentes.
Exemplo
// Configure recall como seu driver de cache// config/cache.php'stores' => [ 'recall' => [ 'driver' => 'recall', ],], // Use como qualquer cache do Laraveluse Illuminate\Support\Facades\Cache; // Primeira chamada: busca do Redis, armazena localmente$user = Cache::store('recall')->get('user:1'); // Chamadas subsequentes: servidas do APCu/Swoole Table local (microsegundos)$user = Cache::store('recall')->get('user:1'); // Quando user:1 é atualizado em qualquer lugar, o Redis notifica o Recall para invalidarCache::store('recall')->put('user:1', $newUserData, 3600);// O cache local é automaticamente invalidado em todos os workers
Instalação
Instale o pacote via Composer:
composer require defectivecode/laravel-recall
Requisitos
- PHP >= 8.4
- Laravel 11.x ou 12.x
- Laravel Octane
- Redis 6.0+ (para suporte a caching do lado do cliente)
- ext-apcu OU ext-swoole (pelo menos um é necessário para caching local)
Uso
Configuração Básica
- Adicione o armazenamento de cache do Recall ao seu
config/cache.php:
'stores' => [ // ... outros armazenamentos 'recall' => [ 'driver' => 'recall', ],],
- Use o armazenamento de cache em sua aplicação:
use Illuminate\Support\Facades\Cache; // Armazene um valor (grava no Redis)Cache::store('recall')->put('key', 'value', 3600); // Recupere um valor (a primeira chamada atinge o Redis, chamadas subsequentes usam o cache local)$value = Cache::store('recall')->get('key'); // Delete um valorCache::store('recall')->forget('key');
Como Funciona
- Primeira Leitura: O valor é buscado no Redis e armazenado no cache local APCu/Swoole Table.
- Leituras Subsequentemente: O valor é servido diretamente da memória local (sub-milisegundos).
- Escrita em Qualquer Lugar: Quando qualquer cliente modifica a chave no Redis, o Redis envia uma mensagem de invalidação.
- Invalidação Automática: O Recall recebe a mensagem e remove a chave do cache local.
- Próxima Leitura: Um novo valor é buscado do Redis e armazenado novamente localmente.
Esse padrão é especialmente poderoso em ambientes Laravel Octane, onde os workers persistem entre as requisições, permitindo que o cache local se acumule e sirva muitas requisições a partir da memória.
Integração com Octane
O Recall se integra automaticamente ao Laravel Octane quando disponível:
- Início do Worker: Estabelece a conexão de invalidação do Redis (início aquecido).
- Requisição Recebida: Processa qualquer mensagem de invalidação pendente.
- Parada do Worker: Fecha conexões de forma graciosa.
Nenhuma configuração adicional é necessária. A integração é automática quando o Octane está instalado.
Configuração
Publique o arquivo de configuração:
php artisan vendor:publish --tag=recall-config
Isso cria o config/recall.php com as seguintes opções:
Habilitar/Desabilitar
'enabled' => env('RECALL_ENABLED', true),
Quando desativado, o Recall passa diretamente para o Redis sem usar a camada de cache local. Útil para depuração ou rolagem gradual.
Armazenamento Redis
'redis_store' => env('RECALL_REDIS_STORE', 'redis'),
O armazenamento de cache do Laravel a ser usado para operações do Redis. Isso deve referenciar um armazenamento Redis configurado em seu
config/cache.php.
Prefixos de Cache
'cache_prefixes' => [],
Armazene localmente apenas chaves que correspondem a esses prefixos. Deixe vazio para armazenar todas as chaves.
// Armazene localmente apenas chaves de usuário e configurações'cache_prefixes' => ['users:', 'settings:', 'config:'],
Isso é útil quando você tem chaves de alto volume que mudam com frequência e não deveriam ser armazenadas localmente.
Configuração do Cache Local
'local_cache' => [ // Driver: "apcu" ou "swoole" 'driver' => env('RECALL_LOCAL_DRIVER', 'apcu'), // Prefixo para chaves de cache local 'key_prefix' => env('RECALL_LOCAL_PREFIX', 'recall:'), // TTL padrão em segundos (rede de segurança se a invalidação for perdida) 'default_ttl' => (int) env('RECALL_LOCAL_TTL', 3600), // Tamanho da Swoole Table (potência de 2, apenas para driver swoole) 'table_size' => (int) env('RECALL_SWOOLE_TABLE_SIZE', 65536), // Máximo de bytes por valor na Swoole Table (apenas para driver swoole) 'value_size' => (int) env('RECALL_SWOOLE_VALUE_SIZE', 8192),],
Driver APCu (Padrão)
O driver APCu funciona com todos os ambientes PHP e servidores Octane (Swoole, RoadRunner, FrankenPHP). Ele armazena os valores em cache na memória compartilhada acessível a todos os processos PHP.
Requisitos:
- ext-apcu instalado e habilitado
apc.enable_cli=1em php.ini para uso em CLI
Driver Swoole Table
O driver Swoole Table utiliza tabelas de memória compartilhada do Swoole, proporcionando acesso consistente entre corrotinas dentro do mesmo worker. Melhor para ambientes Swoole/OpenSwoole.
Dicas de configuração:
table_size: Deve ser uma potência de 2 (por exemplo, 65536, 131072). Determina o número máximo de entradas.value_size: Máximos bytes para valores serializados. Valores maiores são truncados silenciosamente.
Listeners do Octane
'listeners' => [ // Aquecer conexão ao iniciar o worker (reduz a latência da primeira requisição) 'warm' => env('RECALL_LISTEN_WARM', true), // Processar invalidações em eventos de tick (mais responsivo, leve sobrecarga) 'tick' => env('RECALL_LISTEN_TICK', false),],
Conexões Aquecidas
Quando ativado, o Recall estabelece a assinatura de invalidação do Redis quando o worker Octane inicia. Isso elimina a latência de conexão na primeira requisição.
Processamento de Tick
Quando ativado, o Recall processa mensagens de invalidação em eventos de tick do Octane além de eventos de requisição. Isso proporciona uma invalidação de cache mais responsiva com o custo de uma leve sobrecarga adicional.
Uso Avançado
Processamento Manual de Invalidações
Se você precisar processar invalidações manualmente (por exemplo, em um processo de longa duração):
use DefectiveCode\Recall\RecallManager; $manager = app(RecallManager::class);$manager->processInvalidations();
Limpeza do Cache Local
Para limpar apenas o cache local sem afetar o Redis:
use DefectiveCode\Recall\RecallManager; $manager = app(RecallManager::class);$manager->flushLocalCache();
Gerenciamento de Conexões
use DefectiveCode\Recall\RecallManager; $manager = app(RecallManager::class); // Verifique se a assinatura de invalidação está conectadaif ($manager->isConnected()) { // ...} // Desconectar manualmente$manager->disconnect();
Otimização
Limites de Requisições de Worker
O Laravel Octane faz ciclos nos workers após um número configurável de requisições para prevenir vazamentos de memória. Quando um worker roda, seu cache local é limpo. Aumentar esse limite permite que o cache local do Recall persista mais tempo, melhorando as taxas de acerto do cache.
No seu config/octane.php:
// O padrão é 500 requisições antes de reiniciar'max_requests' => 10000,
Valores mais altos significam melhor utilização do cache, mas requer confiança de que sua aplicação não tem vazamentos de memória. Monitore o uso de memória do seu worker ao ajustar esse valor.
Caching Seletivo com Prefixos
Use cache_prefixes para controlar quais chaves são armazenadas localmente. Isso é valioso quando:
- Chaves de alta rotatividade: Algumas chaves mudam tão frequentemente que o caching local oferece pouco benefício.
- Valores grandes: Reduza a pressão na memória armazenando apenas chaves menores e frequentemente lidas.
- Dados sensíveis: Mantenha certos dados apenas no Redis por razões de segurança ou conformidade.
// config/recall.php'cache_prefixes' => [ 'users:', // Armazene dados do usuário localmente 'settings:', // Armazene configurações da aplicação 'products:', // Armazene catálogo de produtos],
Chaves que não correspondem a esses prefixos ainda funcionarão, mas evitarão o caching local, indo diretamente para o Redis.
Considerações de Memória
Memória APCu
APCu compartilha memória entre todos os processos PHP. Configure o limite de memória em php.ini:
; O padrão é 32MB, aumente para necessidades de cache maioresapc.shm_size = 128M
Monitore o uso do APCu com apcu_cache_info():
$info = apcu_cache_info();$memory = $info['mem_size']; // Uso atual de memória em bytes
Dimensionamento da Tabela Swoole
As Tabelas Swoole têm capacidade fixa configurada na criação. Planeje para o seu tamanho de cache esperado:
'local_cache' => [ // Máximo de entradas (deve ser potência de 2) 'table_size' => 65536, // 64K entradas // Tamanho máximo de valor serializado em bytes 'value_size' => 8192, // 8KB por valor],
Uso de memória: table_size × (value_size + overhead). Uma tabela com 65536 entradas e valores de 8KB usa aproximadamente
512MB.
Padrões Comuns
Configuração da Aplicação
// Cache de flags de recursos e configurações$features = Cache::store('recall')->remember('config:features', 3600, function () { return Feature::all()->pluck('enabled', 'name')->toArray();}); // Quando as configurações mudam, todos os workers recebem automaticamente as atualizações
Dados de Referência Acessados com Frequência
// Cache de categorias de produtos$categories = Cache::store('recall')->remember('categories:all', 3600, function () { return Category::with('children')->whereNull('parent_id')->get();}); // Cache de taxas de câmbio$rates = Cache::store('recall')->remember('rates:exchange', 300, function () { return ExchangeRate::all()->pluck('rate', 'currency')->toArray();});
Alternativa a Tags de Cache
O Recall não suporta tags de cache, mas você pode alcançar funcionalidade semelhante com prefixos:
// Em vez de tags, use prefixos consistentesCache::store('recall')->put("blog:posts:{$id}", $post, 3600);Cache::store('recall')->put("blog:comments:{$postId}", $comments, 3600); // Limpe todo o cache relacionado a blogs pelo prefixo (requer implementação manual)// Ou confie na invalidação automática quando os dados mudam
Limitações
Modo Cluster do Redis
O Recall não suporta o modo Cluster do Redis. A opção REDIRECT do comando CLIENT TRACKING requer que tanto a conexão de
dados quanto a conexão de assinante de invalidação estejam no mesmo nó do Redis. Em um cluster, as chaves são distribuídas
por múltiplos nós com base em slots de hash, tornando impossível receber invalidações para chaves armazenadas em diferentes nós.
Para implantações de Redis em cluster, considere:
- Usar uma única instância Redis para dados em cache que se beneficiem do caching do lado do cliente.
- Usar o Redis Cluster para outros dados enquanto mantém dados frequentemente lidos e estáveis em uma instância independente.
Diretrizes de Suporte
Obrigado por escolher nosso pacote de código aberto! Por favor, reserve um momento para conferir estas diretrizes de suporte. Elas ajudarão você a aproveitar ao máximo nosso projeto.
Suporte Direcionado pela Comunidade
Nosso projeto de código aberto é alimentado por nossa incrível comunidade. Se você tiver dúvidas ou precisar de assistência, StackOverflow e outros recursos online são suas melhores opções.
Erros e Priorização de Recursos
A realidade de gerenciar um projeto de código aberto significa que não podemos abordar imediatamente todos os erros ou solicitações de recursos relatados. Priorizamos as questões na seguinte ordem:
1. Erros que Afetam Nossos Produtos Pagos
Erros que impactam nossos produtos pagos serão sempre nossa maior prioridade. Em alguns casos, podemos abordar apenas erros que nos afetam diretamente.
2. Pull Requests da Comunidade
Se você identificou um erro e tem uma solução, por favor, envie um pull request. Após as questões que afetam nossos produtos, damos a próxima maior prioridade a essas correções impulsionadas pela comunidade. Uma vez revisada e aprovada, iremos mesclar sua solução e creditar sua contribuição.
3. Apoio Financeiro
Para questões fora das categorias mencionadas, você pode optar por financiar sua resolução. Cada problema em aberto está vinculado a um formulário de pedido onde você pode contribuir financeiramente. Priorizamos essas questões com base no valor do financiamento fornecido.
Contribuições da Comunidade
O código aberto prospera quando sua comunidade é ativa. Mesmo que você não esteja corrigindo erros, considere contribuir com melhorias de código, atualizações de documentação, tutoriais ou ajudando outros em canais da comunidade. Incentivamos fortemente todos, como comunidade, a ajudar a apoiar o trabalho de código aberto.
Para reiterar, a DefectiveCode priorizará erros com base em como eles impactam nossos produtos pagos, pull requests da comunidade e o apoio financeiro recebido para as questões.
Licença - Licença MIT
Copyright © Defective Code, LLC. Todos os direitos reservados
A permissão é concedida, sem qualquer custo, a qualquer pessoa que obter uma cópia deste software e dos arquivos de documentação associados (o "Software"), para lidar com o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, fundir, publicar, distribuir, sublicenciar e/ou vender cópias do Software, e para permitir que pessoas a quem o Software é fornecido façam o mesmo, sujeito às seguintes condições:
O aviso de copyright acima e este aviso de permissão devem ser incluídos em todas as cópias ou porções substanciais do Software.
O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO A GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM FIM ESPECÍFICO E NÃO INFRAÇÃO. EM NENHUM CASO OS AUTORES OU DETENTORES DO DIREITO AUTORAL SERÃO RESPONSÁVEIS POR QUALQUER RECLAMAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM AÇÃO DE CONTRATO, DELITO OU DE OUTRA FORMA, DECORRENTES DE, EM DECORRÊNCIA OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NO SOFTWARE.