<h2>Cache em PHP: Redis, Memcached e OPcache</h2>
<p>O cache é um dos pilares da otimização de aplicações web modernas. Em PHP, temos três estratégias principais: Redis (cache distribuído com estruturas de dados avançadas), Memcached (cache simples e rápido em memória) e OPcache (cache de opcode do PHP). Cada uma resolve problemas diferentes e, frequentemente, são usadas em conjunto. Entender quando e como aplicar cada uma é essencial para construir sistemas escaláveis e responsivos.</p>
<h3>A Importância do Cache em Aplicações Reais</h3>
<p>Sem cache, sua aplicação executa a mesma lógica repetidamente: consultas ao banco de dados, cálculos pesados, processamento de dados. Isso degrada o desempenho exponencialmente conforme o número de usuários cresce. Cache em memória reduz latência de milissegundos para microssegundos, permitindo que aplicações sirvam centenas de requisições por segundo. É especialmente crítico em operações que envolvem I/O (disco, rede, processamento intensivo).</p>
<p>---</p>
<h2>Redis: Cache Distribuído e Versátil</h2>
<p>Redis é um banco de dados em memória que funciona como cache distribuído com suporte a estruturas de dados sofisticadas (strings, hashes, listas, sets, sorted sets). Diferente do Memcached, Redis permite operações atômicas, expiração granular e persistência opcional. É ideal para sistemas que precisam compartilhar cache entre múltiplos servidores.</p>
<h3>Instalação e Conexão Básica</h3>
<pre><code class="language-php"><?php
// Conexão com Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// Verificar conexão
if ($redis->ping()) {
echo "Conectado ao Redis!";
}
// Armazenar valor simples
$redis->set('user:1:name', 'João Silva', 3600); // Expira em 1 hora
echo $redis->get('user:1:name'); // Saída: João Silva
// Incrementar contador
$redis->incr('page:views');
echo $redis->get('page:views'); // Saída: 1 (ou valor incrementado)
// Usar hash para dados estruturados
$redis->hset('user:2', 'name', 'Maria', 'email', 'maria@example.com');
$user = $redis->hgetall('user:2');
print_r($user); // Array com name e email
// Limpar chave
$redis->del('user:1:name');</code></pre>
<h3>Cache de Resultados de Banco de Dados</h3>
<pre><code class="language-php"><?php
class UserRepository {
private $redis;
private $pdo;
public function __construct($redis, $pdo) {
$this->redis = $redis;
$this->pdo = $pdo;
}
public function getUserById($id) {
$cacheKey = "user:{$id}";
// Tentar obter do cache
$cached = $this->redis->get($cacheKey);
if ($cached !== false) {
return json_decode($cached, true);
}
// Cache miss: buscar do banco
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// Armazenar em cache por 1 hora
if ($user) {
$this->redis->setex($cacheKey, 3600, json_encode($user));
}
return $user;
}
public function invalidateUserCache($id) {
$this->redis->del("user:{$id}");
}
}</code></pre>
<p>---</p>
<h2>Memcached: Simplicidade e Velocidade</h2>
<p>Memcached é um cache distribuído minimalista: apenas armazena pares chave-valor em memória. É extremamente rápido e com overhead mínimo, ideal para aplicações que precisam apenas de cache simples. Não oferece persistência ou estruturas de dados complexas, mas essa simplicidade é sua força — menos código, menos bugs.</p>
<h3>Configuração Básica e Operações</h3>
<pre><code class="language-php"><?php
$memcached = new Memcached();
$memcached->addServer('127.0.0.1', 11211);
// Armazenar dados
$memcached->set('product:123', [
'id' => 123,
'name' => 'Notebook',
'price' => 2500.00
], 1800); // Expira em 30 minutos
// Recuperar dados
$product = $memcached->get('product:123');
echo $product['name']; // Saída: Notebook
// Operações em batch (mais eficiente)
$keys = ['product:1', 'product:2', 'product:3'];
$products = $memcached->getMulti($keys);
// Deletar
$memcached->delete('product:123');
// Verificar status
$stats = $memcached->getStats();
echo "Itens no cache: " . $stats[0]['curr_items'];</code></pre>
<h3>Cache de Resultados de API Externas</h3>
<pre><code class="language-php"><?php
class WeatherService {
private $memcached;
public function __construct($memcached) {
$this->memcached = $memcached;
}
public function getWeather($city) {
$cacheKey = "weather:{$city}";
// Tentar cache primeiro
$weather = $this->memcached->get($cacheKey);
if ($weather !== false) {
return $weather;
}
// Cache miss: chamar API
$response = file_get_contents("https://api.weather.example.com?city={$city}");
$weather = json_decode($response, true);
// Cachear por 6 horas (reduz custos de API)
$this->memcached->set($cacheKey, $weather, 21600);
return $weather;
}
}</code></pre>
<p>---</p>
<h2>OPcache: Cache de Opcode do Motor PHP</h2>
<p>OPcache é diferente: ele não cacheia dados da aplicação, mas sim o código PHP compilado. O PHP é interpretado — cada requisição compila o código-fonte em bytecode (opcode), depois executa. OPcache armazena esse bytecode compilado, eliminando a etapa de compilação em requisições subsequentes. É habilitado por padrão no PHP 5.5+ e oferece ganhos de 20-40% de desempenho com configuração mínima.</p>
<h3>Configuração Recomendada no php.ini</h3>
<pre><code class="language-ini">; Habilitar OPcache
opcache.enable=1
opcache.enable_cli=1
; Tamanho da memória (em MB)
opcache.memory_consumption=128
; Número máximo de scripts em cache
opcache.max_accelerated_files=10000
; Validar scripts a cada N segundos (0 = nunca, em produção)
opcache.revalidate_freq=60
; Estratégia de revalidação (timestamp ou md5)
opcache.validate_timestamps=1
; Interned strings buffer (economiza memória com strings duplicadas)
opcache.interned_strings_buffer=8
; Habilitar JIT compiler (PHP 8+, ganhos até 3x)
opcache.jit=tracing
opcache.jit_buffer_size=100M</code></pre>
<h3>Verificando Status do OPcache</h3>
<pre><code class="language-php"><?php
// Informações sobre o estado do OPcache
if (extension_loaded('Zend OpcacheExtension')) {
$status = opcache_get_status();
echo "Memoria usada: " . $status['memory_usage']['used_memory'] . " bytes\n";
echo "Scripts em cache: " . $status['opcache_statistics']['num_cached_scripts'] . "\n";
echo "Taxa de hit: " . $status['opcache_statistics']['hits'] /
($status['opcache_statistics']['hits'] +
$status['opcache_statistics']['misses']) * 100 . "%\n";
// Limpar cache (útil após deploy)
opcache_reset();
}</code></pre>
<p>---</p>
<h2>Conclusão</h2>
<p>Dominando esses três mecanismos, você constrói aplicações verdadeiramente escaláveis. <strong>Redis</strong> é sua ferramenta versátil para cache distribuído com estruturas complexas e operações atômicas. <strong>Memcached</strong> brilha em cenários simples onde velocidade bruta é prioridade. <strong>OPcache</strong> é a base — sempre ativo, oferecendo ganhos automáticos de compilação. Use Redis/Memcached para dados da aplicação (resultados de banco, APIs externas) e confie no OPcache para otimização transparente do motor PHP. A combinação desses três gera sistemas que servem milhões de requisições com latência minimal.</p>
<p>---</p>
<h2>Referências</h2>
<ul>
<li><a href="https://redis.io/documentation" target="_blank" rel="noopener noreferrer">Redis Official Documentation</a></li>
<li><a href="https://memcached.org/" target="_blank" rel="noopener noreferrer">Memcached Official Wiki</a></li>
<li><a href="https://www.php.net/manual/en/book.opcache.php" target="_blank" rel="noopener noreferrer">PHP OPcache Manual</a></li>
<li><a href="https://www.oreilly.com/library/view/high-performance-php/9781492044529/" target="_blank" rel="noopener noreferrer">High Performance PHP - Scalable Systems Design</a></li>
<li><a href="https://www.manning.com/books/redis-in-action" target="_blank" rel="noopener noreferrer">Redis in Action</a></li>
</ul>