Memcached
Casos de uso ideais
Aprenda quando um cache simples oferece mais desempenho e menor custo operacional.
Nesta aula você vai
- Identificar workloads onde Memcached supera alternativas mais complexas
- Aplicar padrões de chave, TTL e invalidação adequados ao modelo Memcached
- Reconhecer limitações que impedem uso de Memcached em certos cenários
Casos de uso ideais
Objetivos
Nesta aula você vai:
- Mapear cenários de produção onde Memcached ainda é escolha técnica sólida
- Implementar padrões de cache com TTL, namespacing e proteção contra stampede
- Listar anti-padrões que indicam migração para Redis/Valkey ou outra solução
Introdução
Memcached não desapareceu com Redis — grandes propriedades web mantêm farms de Memcached por previsibilidade, footprint de memória e simplicidade operacional em cache puro. A chave é usar onde o problema é estritamente "acelerar leitura de blob serializado" sem necessidade de estruturas, durabilidade ou coordenação complexa.
Esta aula é pragmática: quando Memcached é ideal, como usá-lo bem, e quando forçá-lo além do design gera fragilidade.
Conteúdo
Perfil ideal de workload
| Característica | Alinhamento com Memcached |
|---|---|
| Valores opacos (HTML fragment, JSON serializado) | Excelente |
| Leitura >> escrita | Excelente |
| Perda total após restart aceitável | Obrigatório |
| TTL uniforme ou por classe de dado | Natural |
| Múltiplos nós com hash no cliente | Padrão estabelecido |
| Necessidade de fila ou ranking | Inadequado |
Exemplos clássicos:
- Fragmentos de página renderizada (edge include cache)
- Resultado de query SQL pesada serializado
- Objeto de sessão se serialização completa a cada request for aceitável (muitas equipes migraram sessão para Redis hash)
- Rate limit muito simples via
incr(sem janela deslizante sofisticada)
Padrões de modelagem de chaves
Namespaces evitam colisão entre aplicações compartilhando cluster:
{app}:{env}:{entidade}:{id}
ex: shop:prod:product:991
shop:prod:category:12:page:3
Versão na chave para invalidação em massa sem flush_all:
catalog:v2026-07-08:product:991
Deploy novo → bump versão no prefixo; chaves antigas expiram por TTL.
TTL e invalidação
Memcached não notifica aplicação sobre evicção — TTL expira silenciosamente.
Cache-aside permanece padrão:
getchave- Miss → origem →
setcom TTL - Hit → retorna
Invalidação em update:
deletechave conhecida — simples- Sem scan de chaves — não existe
KEYS * - Invalidação por tag exige indireção na app ou chave versão
TTL típicos:
| Tipo de dado | TTL sugerido |
|---|---|
| Página estática cacheada | 5–60 min |
| Catálogo semi-estático | 15–120 min |
| Contador volátil | 1–5 min ou sem cache |
| Dado personalizado por usuário | Curto (30s–5min) ou não cachear em Memcached compartilhado |
Escalando e protegendo o cache
Pool de nós: cliente com consistent hashing; adicione capacidade horizontal antes de RAM máxima por host.
Mcrouter / proxy: roteamento, warm standby, prefix routing para multi-tenant.
Stampede / dogpile: em miss massivo, múltiplas threads batem na origem — mitigue com:
- Lock leve na aplicação (mutex por chave)
- Valor placeholder com TTL curto enquanto reconstrói
- Single-flight pattern na lib
Memcached não oferece SET NX tão ergonomicamente quanto Redis — lógica fica na aplicação.
Quando NÃO usar Memcached
| Requisito | Alternativa |
|---|---|
| Persistência após restart | Redis/Valkey com AOF |
| Estruturas (hash field parcial) | Redis hash |
| Pub/Sub notificações | Redis Pub/Sub, Kafka |
| Fila de jobs durável | Redis Streams, SQS |
| Replicação automática | Redis Sentinel/Cluster |
| Geo-distributed active-active | Redis Enterprise ou redesign |
Forçar Memcached como fila com add/get em loop é anti-padrão frágil.
Exemplos práticos
Cache de resultado de API em pseudofluxo:
# Miss — aplicação consulta API e grava (valor JSON de 240 bytes, TTL 600s)
printf "set api:weather:sp 0 600 240\r\n{\"temp\":22,...}\r\n" | nc -q 1 localhost 11211
# Hit subsequente
printf "get api:weather:sp\r\n" | nc -q 1 localhost 11211
Contador de visualizações (string numérica obrigatória):
printf "set views:post:100 0 0 1\r\n0\r\n" | nc -q 1 localhost 11211
printf "incr views:post:100 1\r\n" | nc -q 1 localhost 11211
Monitorar eficiência:
printf "stats\r\n" | nc -q 1 localhost 11211 | egrep 'get_hits|get_misses|curr_items|bytes'
Calcule hit rate ≈ get_hits / (get_hits + get_misses). Abaixo de 80% em cache dedicado merece investigação (TTL curto demais, chaves erradas, evictions).
Resumo
- Memcached brilha em cache read-heavy de valores opacos sem durabilidade.
- Namespacing, TTL e versionamento de chave compensam ausência de estruturas e scan.
- Escale com mais nós e clientes/proxies de hash — não espere cluster server-side.
- Evite filas, sessões complexas e coordenação — use Redis/Valkey ou broker adequado.
- Próxima aula confronta Memcached e Redis lado a lado para decisão arquitetural final do módulo.