Redis: O padrão da indústria

Arquitetura do Redis

Entenda a arquitetura interna, modelo single-thread, estruturas de dados e gerenciamento de memória do Redis.

Intermediário 45 min 30 pontos Leitura 0%

Nesta aula você vai

  • Descrever o modelo single-threaded do Redis e suas implicações de performance
  • Explicar o protocolo RESP e o ciclo comando-resposta do servidor
  • Mapear componentes internos: event loop, dict, expiração e alocação de memória

Arquitetura do Redis

Objetivos

Nesta aula você vai:

  • Compreender como o Redis processa conexões e comandos internamente
  • Entender por que o modelo single-threaded não impede alto throughput
  • Identificar gargalos reais: rede, memória, comandos O(N) e persistência

Introdução

Redis parece um servidor monolítico simples — e, em muitos aspectos, é deliberadamente assim. Por baixo do redis-cli, porém, há um event loop baseado em epoll/kqueue, um protocolo binário-texto híbrido chamado RESP, e estruturas C altamente otimizadas (dict, quicklist, intset, skiplist). Conhecer essa arquitetura evita mitos ("preciso de mais threads no Redis") e orienta tuning em produção.

Conteúdo

Visão geral do processo servidor

Um nó Redis típico executa um único processo principal que:

  1. Aceita conexões TCP (porta 6379 por padrão)
  2. Lê comandos no protocolo RESP
  3. Executa o comando na estrutura de dados em memória
  4. Enfileira resposta no buffer do cliente
  5. Repete, intercalando tarefas de background (AOF fsync, expiração lazy/active)
Cliente ──TCP/RESP──► [ Event Loop ] ──► Dict de chaves
                           │
                           ├──► Expiration (passive/active)
                           ├──► Replication buffer → réplicas
                           └──► AOF/RDB (threads auxiliares em versões recentes)

A partir do Redis 6+, I/O threads opcionais paralelizam leitura/escrita de rede; o núcleo de execução de comandos permanece single-threaded por instância — decisão de design para evitar locks em estruturas compartilhadas.

Protocolo RESP (REdis Serialization Protocol)

RESP tipifica mensagens em tipos simples:

Prefixo Tipo Exemplo
+ Simple string +OK
- Error -ERR unknown command
: Integer :1000
$ Bulk string $5\r\nhello
* Array *2\r\n$3\r\nGET\r\n$3\r\nkey

O cliente envia arrays de bulk strings; o servidor responde conforme o comando. Essa simplicidade permitiu clientes em dezenas de linguagens com parsing mínimo.

Exemplo manual equivalente a SET chave valor:

redis-cli --raw

Internamente, redis-cli serializa *3\r\n$3\r\nSET\r\n$5\r\nchave\r\n$5\r\nvalor\r\n.

Modelo de memória e chaves

Cada chave vive em um dict (hash table). O valor é um redisObject com tipo (string, list, hash, set, zset, stream…) e encoding interno que pode mudar conforme tamanho (ex.: ziplisthashtable após limiar).

Políticas importantes:

  • maxmemory: teto de RAM; acima disso, eviction conforme política (volatile-lru, allkeys-lfu, etc.)
  • active expire: amostragem periódica remove chaves com TTL vencido
  • lazy free: liberação assíncrona de objetos grandes (UNLINK vs DEL)

Por que single-threaded escala?

Operações em RAM são microssegundos. Um core moderno pode executar centenas de milhares de comandos simples por segundo. O gargalo costuma ser:

  • Latência de rede entre app e Redis
  • Comandos O(N) (KEYS *, SMEMBERS em set enorme)
  • Valores grandes — serialização e banda
  • Persistência síncronaappendfsync always
  • Muitas conexões mal gerenciadas (use connection pool)

Paralelismo horizontal vem de múltiplas instâncias ou Cluster, não de threads competindo pelo mesmo dict.

Módulos e extensibilidade

Redis suporta módulos dinâmicos (RedisJSON, RediSearch, RedisBloom…) carregados em runtime. Eles estendem o servidor com novos comandos e tipos, mantendo o event loop. Em arquiteturas que dependem de busca full-text ou JSON nativo, módulos reduzem round-trips à aplicação — com custo de memória e complexidade operacional adicional.

Exemplos práticos

Inspecionar configuração e role do nó:

redis-cli INFO server
redis-cli CONFIG GET io-threads
redis-cli CONFIG GET maxmemory-policy

Medir custo de comando perigoso vs alternativa:

# Evite em produção — O(N) em todas as chaves
KEYS *

# Prefira iteração incremental
SCAN 0 MATCH user:* COUNT 100

Monitorar comandos lentos:

CONFIG SET slowlog-log-slower-than 10000
SLOWLOG GET 10

Slowlog registra comandos acima de 10 ms (10 000 µs) — ferramenta essencial para diagnosticar arquitetura mal utilizada.

Resumo

  • Redis usa event loop single-threaded para execução de comandos, com I/O threads opcionais e workers para persistência.
  • RESP é protocolo simples cliente-servidor que alimenta todo o ecossistema de clientes.
  • Dados organizam-se em dict com encodings adaptativos e políticas de memória/eviction.
  • Performance limita-se mais por rede, comandos O(N) e persistência do que por falta de threads.
  • SCAN, connection pooling e dimensionamento horizontal são respostas arquiteturais corretas — não "um Redis maior" sem análise.