Memcached

Arquitetura do Memcached

Conheça a filosofia minimalista do Memcached e como ele difere do Redis.

Intermediário 40 min 28 pontos Leitura 0%

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.