Memcached
Arquitetura do Memcached
Conheça a filosofia minimalista do Memcached e como ele difere do Redis.
Nesta aula você vai
- Descrever a arquitetura multi-threaded e baseada em slab allocation do Memcached
- Explicar o protocolo texto simples e o modelo de sharding no cliente
- Diferenciar filosofia de design minimalista do Memcached em relação ao Redis
Arquitetura do Memcached
Objetivos
Nesta aula você vai:
- Compreender como o Memcached organiza memória, threads e conexões
- Entender slab allocation e por que fragmentação é controlada de forma diferente
- Reconhecer limitações intencionais: sem persistência, sem estruturas ricas, sem replicação nativa
Introdução
Memcached nasceu em 2003 no LiveJournal para aliviar carga de leitura no MySQL — antes do Redis existir. Sua proposta é radicalmente minimalista: cache distribuído de pares chave-valor, volátil, rápido, com protocolo texto trivial. Não tenta ser banco de dados, fila ou plataforma de mensagens.
Essa simplicidade explica longevidade em stacks LAMP e em camadas de cache CDN-like. Compreender a arquitetura interna ajuda a decidir se Memcached ainda merece lugar no seu diagrama — ou se Redis/Valkey absorveu o caso de uso.
Conteúdo
Modelo de processo e threads
Memcached usa múltiplas threads:
- Thread principal aceita conexões
- Worker threads processam comandos (modelo varia por versão — libevent, thread pool)
- Contraste com Redis: vários cores ativos para I/O e GET/SET simultâneos em instância única
Para workload puramente cache read-heavy, threads podem elevar throughput em CPU multicore sem Cluster. O custo é sincronização e modelo mental mais complexo em tuning de contenda.
Slab allocation — coração da gestão de memória
Em vez de malloc por objeto, Memcached pré-aloca slabs de tamanhos fixos (classes):
Slab class 1: 96 bytes
Slab class 2: 120 bytes
Slab class 3: 152 bytes
...
Cada item armazenado ocupa a menor classe que comporta chave + valor + metadata. Desperdício interno (internal fragmentation) ocorre se valor de 100 bytes cai em classe de 152 bytes.
| Aspecto | Implicação |
|---|---|
| Tamanho máximo de valor | Configurável (-I item size max); típico 1 MB |
| Evicção | LRU por slab class quando memória cheia |
| Crescimento | -m define memória total; slabs não encolhem facilmente |
Comando de estatísticas:
echo "stats slabs" | nc localhost 11211
echo "stats items" | nc localhost 11211
Protocolo e comandos
Protocolo texto na porta 11211 (binário opcional em clientes):
set minha-chave 0 3600 5
hello
get minha-chave
delete minha-chave
| Comando | Função |
|---|---|
set |
Armazena, substitui se existir |
add |
Só se chave não existir |
replace |
Só se chave existir |
get / gets |
Leitura (gets com CAS) |
incr / decr |
Contador em string numérica |
delete |
Remove chave |
flush_all |
Limpa tudo (perigoso em prod) |
Flags (0 no exemplo) são opacos para o servidor — aplicação codifica metadados (tipo, compressão).
CAS (compare-and-swap) com gets/cas evita overwrite concorrente — análogo otimista a WATCH no Redis, mas limitado a string única.
Distribuição horizontal — no cliente
Memcached não possui cluster server-side. Clientes (libmemcached, spymemcached, Mcrouter) aplicam consistent hashing sobre lista de nós:
hash(chave) → nó responsável
Adicionar nó causa remapping parcial — cache warming necessário. Ferramentas como Mcrouter da Meta adicionam pooling, failover e routing na camada de proxy.
O que Memcached deliberadamente não faz
- Persistência em disco
- Replicação built-in
- Pub/Sub, filas, sorted sets
- Transações ou Lua
- ACL/TLS nativos (depende de proxy/stunnel)
Cada omissão reduz superfície de falha e latência — filosofia do one thing well.
Exemplos práticos
Subir Memcached localmente:
docker run -d --name memcached -p 11211:11211 memcached:1.6-alpine -m 128 -vv
Operações básicas via nc ou cliente:
printf "set produto:42 0 300 8\r\nSKU-991\r\n" | nc -q 1 localhost 11211
printf "get produto:42\r\n" | nc -q 1 localhost 11211
Verificar uso de memória e hit rate:
printf "stats\r\n" | nc -q 1 localhost 11211 | grep -E 'curr_items|bytes|get_hits|get_misses|evictions'
evictions crescente indica RAM insuficiente ou TTL mal calibrado — sinal de capacity planning.
Resumo
- Memcached é cache multi-threaded, volátil e minimalista, otimizado para GET/SET em escala.
- Slab allocation controla fragmentação com classes de tamanho fixo — atenção a item size max e desperdício.
- Sharding é responsabilidade do cliente ou proxy (Mcrouter), não do servidor.
- Sem persistência nem estruturas ricas — por design, não por omissão acidental.
- Próximas aulas cobrem casos de uso ideais e comparação direta com Redis/Valkey.