Cheatsheet Redis
Base de dados em memória (chave-valor)
Redis
Comandos Básicos
Conexão (redis-cli)
redis-cli # ligar local (6379) redis-cli -h 192.168.1.10 # host remoto redis-cli -p 6380 # porta custom redis-cli -a minha_senha # com password redis-cli -n 2 # base de dados 2 redis-cli --tls # com TLS
redis-cli é o cliente de linha de comandos. -h define host, -p porta, -a password. -n seleciona a base de dados (0-15 por padrão).
Selecionar base de dados
SELECT 0 # base de dados 0 (padrão) SELECT 1 # base de dados 1 DBSIZE # nº de chaves na BD atual MOVE chave 1 # mover chave para BD 1 FLUSHDB # limpar BD atual (CUIDADO!)
O Redis tem 16 bases de dados lógicas (0-15) por padrão. SELECT muda entre elas. São isoladas mas partilham memória. Em produção, prefere instâncias separadas ou namespaces com prefixos.
Primeiros comandos
PING # responde PONG SET nome "Ana" # guardar valor GET nome # ler → "Ana" DEL nome # eliminar chave EXISTS nome # chave existe? (1/0) TYPE nome # tipo do valor
PING testa a conexão. SET guarda, GET lê, DEL elimina. EXISTS verifica presença. TYPE retorna o tipo: string, list, hash, set, zset.
SCAN (iteração segura)
SCAN 0 MATCH user:* COUNT 100 # → [cursor, [chaves...]] SCAN 17 MATCH user:* COUNT 100 # continua do cursor 17 # Cursor 0 = terminou # HSCAN, SSCAN, ZSCAN para tipos compostos
SCAN itera chaves sem bloquear o servidor. Retorna um cursor e um lote. Repete até cursor = 0. HSCAN para hashes, SSCAN para sets, ZSCAN para sorted sets.
Gerir chaves
KEYS user:* # chaves com padrão SCAN 0 MATCH user:* COUNT 100 # iterativo (seguro) TYPE chave # tipo do valor RENAME old new # renomear chave RANDOMKEY # chave aleatória OBJECT ENCODING chave # representação interna
KEYS retorna todas as chaves que correspondem ao padrão — bloqueia em produção! Usa SCAN como alternativa iterativa e segura. OBJECT ENCODING mostra a estrutura interna.
DEL e UNLINK
DEL chave1 chave2 chave3 # síncrono (bloqueia) UNLINK chave1 chave2 # assíncrono (background) # UNLINK liberta memória em thread separada # Ideal para chaves grandes (listas, hashes) # Retorna nº de chaves removidas
DEL remove síncronamente — pode bloquear com chaves grandes. UNLINK (Redis 4+) remove em background sem bloquear. Prefere UNLINK em produção para chaves com muitos elementos.
Tipos de dados
string # texto ou número (SET/GET) list # lista ordenada (LPUSH/RPUSH) hash # objeto com campos (HSET/HGET) set # conjunto único (SADD) zset # conjunto ordenado por score (ZADD) stream # fluxo de eventos (XADD) bitmap # bits individuais (SETBIT) hyperloglog # contagem aproximada (PFADD)
O Redis tem 8 tipos de dados. string é o mais versátil. hash modela objetos. zset é ideal para rankings. stream para filas persistentes. Cada tipo tem comandos específicos.
COPY e OBJECT
COPY origem destino # copiar chave COPY origem destino DB 1 # copiar para outra BD COPY origem destino REPLACE # sobrescrever destino OBJECT ENCODING chave # int, embstr, raw, listpack... OBJECT IDLETIME chave # segundos sem acesso OBJECT FREQ chave # frequência (LFU)
COPY (Redis 6.2+) duplica uma chave. OBJECT ENCODING mostra a representação interna. IDLETIME indica há quanto tempo não é acedida. Útil para debugging e otimização.
Strings
SET e GET
SET cidade "Lisboa" GET cidade # "Lisboa" # Opções do SET: SET token "abc" EX 60 # expira em 60s SET chave "v" NX # só se NÃO existir SET chave "v" XX # só se existir SET chave "v" KEEPTTL # manter TTL existente
SET guarda um valor. GET lê. Opções: EX (segundos), PX (ms), NX (criar só), XX (atualizar só), KEEPTTL preserva expiração.
SET com expiração
SET sessao "xyz" EX 3600 # 1 hora SET temp "v" PX 5000 # 5000 milissegundos SET lock "1" NX EX 10 # lock de 10s (só se não existir) SET cache "html" EXAT 1700000000 # timestamp Unix # EX = segundos, PX = milissegundos # EXAT = timestamp absoluto, PXAT = ms absoluto
Combina SET com TTL numa operação atómica. NX EX é o padrão para distributed locks. EXAT define expiração por timestamp absoluto. Evita race conditions vs SET + EXPIRE separados.
Contadores (INCR/DECR)
SET visitas 10 INCR visitas # 11 INCRBY visitas 5 # 16 DECR visitas # 15 DECRBY visitas 3 # 12 INCRBYFLOAT preco 1.5 # soma decimal # Se chave não existe, começa em 0 INCR nova_chave # 1
INCR/DECR são operações atómicas — seguras em concorrência. Ideais para contadores, rate limiting e IDs sequenciais. INCRBY soma N. INCRBYFLOAT para decimais.
Bitmaps
SETBIT presenca 0 1 # bit 0 = 1 SETBIT presenca 1 0 # bit 1 = 0 GETBIT presenca 0 # 1 BITCOUNT presenca # total de bits a 1 BITPOS presenca 1 # posição do primeiro 1 BITOP AND resultado set1 set2 # operação entre bitmaps
Bitmaps operam a nível de bit sobre strings. Ultra-compactos para flags (presença, login diário). BITCOUNT conta bits ativos. 1 MB armazena ~8 milhões de flags. Ideal para analytics.
MSET e MGET (lote)
MSET a "1" b "2" c "3" # guardar várias MGET a b c # ["1", "2", "3"] MSETNX a "1" b "2" # só se NENHUMA existir # MGET retorna nil para chaves inexistentes MGET a inexistente c # ["1", nil, "3"]
MSET/MGET operam em múltiplas chaves numa chamada — reduz round-trips. MSETNX é atómico: só define se nenhuma chave existir. Mais eficiente que SET/GET individuais.
HyperLogLog
PFADD visitas "user1" "user2" "user3" PFADD visitas "user2" "user4" PFCOUNT visitas # 4 (únicos aproximados) PFMERGE total set1 set2 # unir contagens # Erro padrão: ~0.81% # Usa só 12 KB de memória (vs milhões em SET)
HyperLogLog conta elementos únicos com memória mínima (12 KB). Erro ~0.81%. Ideal para contagem de visitantes únicos, UVs. PFADD adiciona, PFCOUNT estima, PFMERGE une.
Manipular strings
APPEND nome " Silva" # acrescentar ao fim STRLEN nome # comprimento SETRANGE nome 0 "X" # substituir posição GETRANGE nome 0 3 # sub-string GETDEL nome # ler e apagar (6.2+) GETSET nome "novo" # trocar e devolver antigo
APPEND concatena. STRLEN dá o tamanho. GETRANGE extrai sub-string. GETDEL (6.2+) lê e remove atomicamente. Strings até 512 MB de tamanho máximo.
GETEX e GETDEL
# Ler e definir TTL atomicamente (6.2+) GETEX chave EX 60 # ler + expirar em 60s GETEX chave PERSIST # ler + remover TTL # Ler e apagar atomicamente (6.2+) GETDEL chave # retorna valor e remove # Útil para one-time tokens: SET otp "1234" EX 300 GETDEL otp # usa uma vez e apaga
GETEX (6.2+) lê e ajusta TTL numa operação. GETDEL lê e remove atomicamente — ideal para tokens de uso único. Evita race conditions entre GET e DEL/EXPIRE separados.
Listas
Adicionar elementos
LPUSH fila "a" # início (esquerda) RPUSH fila "b" # fim (direita) LPUSH fila a b c # vários de uma vez LINSERT fila BEFORE "b" "x" # inserir antes LLEN fila # comprimento LINDEX fila 0 # elemento por índice
LPUSH insere à esquerda, RPUSH à direita. LINSERT insere antes/depois de um valor. LLEN dá o tamanho. Listas mantêm ordem de inserção e aceitam duplicados.
Blocking pop (BLPOP/BRPOP)
# Espera até haver elemento ou timeout BLPOP fila 30 # timeout 30s BRPOP fila 0 # espera infinita # Múltiplas filas (prioridade): BLPOP alta media baixa 30 # verifica "alta" primeiro # Retorna nil se timeout expirar
BLPOP/BRPOP bloqueiam até haver dados. Ideais para workers que esperam tarefas. Timeout 0 = espera infinita. Múltiplas listas = prioridade (primeira com dados é consumida).
Ler elementos
LRANGE fila 0 -1 # todos os elementos LRANGE fila 0 9 # primeiros 10 LRANGE fila -5 -1 # últimos 5 LPOP fila # remover e retornar do início RPOP fila # remover e retornar do fim LPOP fila 3 # remover 3 do início (6.2+) LMPOP 2 fila1 fila2 LEFT # pop de múltiplas listas
LRANGE lê sem remover (0 = primeiro, -1 = último). LPOP/RPOP removem e retornam. Desde 6.2+, LPOP N remove múltiplos. LMPOP opera em várias listas.
LSET e LREM
# Atualizar por índice LSET fila 0 "novo_valor" # Remover por valor LREM fila 2 "elemento" # remove 2 ocorrências LREM fila 0 "elemento" # remove TODAS LREM fila -1 "elemento" # remove 1 do fim # Trim (manter só N elementos) LTRIM fila 0 99 # manter primeiros 100
LSET atualiza por índice. LREM remove por valor (count positivo = do início, negativo = do fim, 0 = todos). LTRIM trunca a lista — útil para limitar tamanho.
Fila (FIFO)
# Producer: adicionar ao fim RPUSH tarefas "job1" RPUSH tarefas "job2" RPUSH tarefas "job3" # Consumer: remover do início LPOP tarefas # "job1" (primeiro a entrar) LPOP tarefas # "job2" # RPUSH + LPOP = FIFO (First In, First Out)
Padrão FIFO: RPUSH para produzir, LPOP para consumir. O primeiro a entrar é o primeiro a sair. Base para filas de mensagens e task queues simples.
RPOPLPUSH (mover entre listas)
# Mover elemento de uma lista para outra RPOPLPUSH origem destino # Caso de uso: fila de processamento RPUSH tarefas "job1" RPOPLPUSH tarefas em_processo # ... processar ... LREM em_processo 1 "job1" # LMOVE (6.2+, mais flexível): LMOVE origem destino RIGHT LEFT
RPOPLPUSH move atomicamente do fim de uma lista para o início de outra. Padrão de fila fiável: item fica em "processing" até confirmação. LMOVE (6.2+) permite escolher lados.
Pilha (LIFO)
# Push: adicionar ao início LPUSH pilha "a" LPUSH pilha "b" LPUSH pilha "c" # Pop: remover do início LPOP pilha # "c" (último a entrar) LPOP pilha # "b" # LPUSH + LPOP = LIFO (Last In, First Out)
Padrão LIFO: LPUSH + LPOP (mesmo lado). O último a entrar é o primeiro a sair. Útil para stacks, undo/redo, histórico de navegação.
Lista como log circular
# Manter só os últimos 1000 eventos RPUSH log:evento "erro: timeout" LTRIM log:evento -1000 -1 # Ler últimos 10 LRANGE log:evento -10 -1 # Padrão: RPUSH + LTRIM = tamanho fixo # Nunca cresce além do limite
Combina RPUSH + LTRIM para log com tamanho fixo. LTRIM -N -1 mantém só os últimos N. Eficiente em memória. Ideal para activity feeds, logs recentes e histórico limitado.
Hashes
Criar hash (HSET)
HSET user:1 nome "Ana" idade 30 cidade "Porto" # Ou campo a campo: HSET user:1 nome "Ana" HSET user:1 idade 30 # Só se não existir: HSETNX user:1 email "ana@mail.com" HGET user:1 nome # "Ana"
HSET define campos num hash. Aceita múltiplos pares campo-valor. HSETNX só define se o campo não existir. HGET lê um campo. Ideal para modelar objetos.
HSCAN (iterar hash grande)
HSCAN user:1 0 MATCH nome* COUNT 100 # → [cursor, [campo, valor, ...]] # Iterar todos os campos: HSCAN user:1 0 COUNT 1000 # repetir com cursor retornado até 0 # Essencial para hashes com milhares de campos
HSCAN itera campos de um hash sem bloquear. Essencial para hashes grandes (milhares de campos). Retorna cursor + lote. Repetir até cursor = 0. Nunca usar HGETALL em hashes enormes.
Ler hash
HGETALL user:1 # todos os campos e valores HGET user:1 nome # um campo HMGET user:1 nome idade cidade # vários campos HKEYS user:1 # nomes dos campos HVALS user:1 # só os valores HLEN user:1 # nº de campos HSTRLEN user:1 nome # tamanho do valor
HGETALL retorna tudo (cuidado com hashes grandes). HMGET campos específicos. HKEYS/HVALS separam nomes e valores. HLEN conta campos.
HRANDFIELD (6.2+)
# Campo aleatório HRANDFIELD user:1 # 3 campos aleatórios (sem repetição) HRANDFIELD user:1 3 # Com valores: HRANDFIELD user:1 3 WITHVALUES # Com repetição (count negativo): HRANDFIELD user:1 -5
HRANDFIELD (6.2+) retorna campos aleatórios. Count positivo = sem repetição, negativo = com repetição. WITHVALUES inclui valores. Útil para sorteios e amostras.
Atualizar e eliminar campos
HSET user:1 idade 31 # atualizar HINCRBY user:1 idade 1 # incrementar (32) HINCRBYFLOAT user:1 saldo 9.5 # decimal HDEL user:1 cidade # remover campo HEXISTS user:1 nome # campo existe? (1/0) HDEL user:1 campo1 campo2 # remover vários
HSET sobrescreve o campo. HINCRBY incrementa atomicamente. HDEL remove campos. HEXISTS verifica presença. Operações em campos individuais são eficientes.
Hash vs String (quando usar)
# Hash: objeto com múltiplos campos
HSET user:1 nome "Ana" idade 30 email "a@b.com"
# → update parcial: HSET user:1 idade 31
# Strings: valores simples ou serializados
SET user:1:nome "Ana"
SET user:1:json '{"nome":"Ana","idade":30}'
# → update total: reescrever JSON inteiroUsa hash para objetos com updates parciais frequentes. Usa string para valores simples ou dados sempre lidos/escritos em conjunto. Hash economiza memória com muitos campos pequenos.
Hash como objeto (modelação)
# Modelar um produto HSET produto:100 nome "TV 4K" preco 500 stock 10 ativo 1 # Operações típicas: HGETALL produto:100 HINCRBY produto:100 stock -1 # vender HSET produto:100 ativo 0 # desativar HMGET produto:100 nome preco # campos específicos
Hashes são perfeitos para modelar objetos: cada campo é uma propriedade. Convenção: tipo:id como chave. Mais eficiente que múltiplas strings. Suporta updates parciais sem reescrever tudo.
Hash com TTL (7.4+)
# TTL por campo (Redis 7.4+) HSET sessao:abc user "ana" EX 3600 HSET sessao:abc token "xyz" EX 600 HEXPIRE sessao:abc 300 FIELDS user token HTTL sessao:abc FIELDS user HPERSIST sessao:abc FIELDS token # Antes do 7.4: TTL só na chave inteira EXPIRE sessao:abc 3600
Desde Redis 7.4+, campos de hash podem ter TTL individual com HSET ... EX e HEXPIRE. Antes, só a chave inteira expirava. Útil para sessões com campos de validade diferente.
Sets e Sorted Sets
Sets (conjuntos únicos)
SADD tags "php" "redis" "docker" SMEMBERS tags # todos os membros SISMEMBER tags "php" # pertence? (1/0) SMISMEMBER tags "php" "go" # múltiplos (6.2+) SCARD tags # nº de membros SREM tags "php" # remover membro
SADD adiciona (ignora duplicados). SMEMBERS lista tudo. SISMEMBER verifica pertença em O(1). SCARD conta. Sets não têm ordem e não aceitam repetidos.
Rankings e leaderboards
ZREVRANGE ranking 0 2 WITHSCORES # top 3 (desc) ZRANK ranking "ana" # posição (asc, 0-based) ZREVRANK ranking "ana" # posição (desc) ZINCRBY ranking 5 "ana" # +5 pontos ZCOUNT ranking 90 100 # quantos entre 90-100 ZREMRANGEBYRANK ranking 0 9 # remover bottom 10
ZREVRANGE = top N (maior score primeiro). ZRANK/ZREVRANK dão a posição. ZINCRBY incrementa score. Padrão perfeito para leaderboards em tempo real.
Operações entre sets
SINTER a b # interseção (elementos comuns) SUNION a b # união (todos sem duplicados) SDIFF a b # diferença (em a mas não em b) # Guardar resultado: SINTERSTORE resultado a b SUNIONSTORE resultado a b # Cardinalidade da interseção (sem guardar): SINTERCARD 2 a b LIMIT 10
SINTER = elementos comuns. SUNION = todos combinados. SDIFF = só no primeiro. Versões *STORE guardam resultado. SINTERCARD (7+) conta sem materializar.
Ranges por score
ZRANGEBYSCORE ranking 80 100 # scores 80-100 ZRANGEBYSCORE ranking (80 100 # exclusivo: >80 ZREVRANGEBYSCORE ranking 100 80 # descendente ZREMRANGEBYSCORE ranking 0 50 # remover ≤50 ZRANGEBYSCORE ranking -inf +inf # todos # Com paginação: ZRANGEBYSCORE ranking 0 100 LIMIT 0 10
ZRANGEBYSCORE filtra por intervalo de score. ( torna exclusivo. -inf/+inf para limites abertos. LIMIT offset count pagina. Útil para filtros por preço, tempo, prioridade.
SPOP e SRANDMEMBER
SPOP sorteio # remover e retornar aleatório SPOP sorteio 3 # remover 3 aleatórios SRANDMEMBER sorteio # ver aleatório (sem remover) SRANDMEMBER sorteio 5 # 5 aleatórios (sem remover) # SMOVE: mover entre sets SMOVE origem destino "elemento"
SPOP remove aleatoriamente (sorteios, lotarias). SRANDMEMBER vê sem remover (amostras). SMOVE transfere entre sets atomicamente. Todos O(1) ou O(N) conforme count.
ZRANGEBYLEX (lexicográfico)
# Todos com mesmo score → ordenação alfabética ZADD nomes 0 "ana" 0 "bruno" 0 "carla" 0 "david" ZRANGEBYLEX nomes [ana [carla # ana a carla ZRANGEBYLEX nomes (ana + # depois de "ana" ZREMRANGEBYLEX nomes [a [b # remover a-b ZLEXCOUNT nomes [a [z # contar no range
Quando todos os scores são iguais, ZRANGEBYLEX ordena lexicograficamente. [ = inclusivo, ( = exclusivo. Útil para autocomplete e dicionários ordenados.
Sorted Sets (ZADD)
ZADD ranking 100 "ana" 85 "joão" 92 "maria" ZRANGE ranking 0 -1 WITHSCORES # todos com scores ZSCORE ranking "ana" # 100 ZCARD ranking # nº de membros ZMSCORE ranking "ana" "joão" # múltiplos scores ZADD ranking 95 "ana" # atualizar score
ZADD adiciona com score (ou atualiza). ZRANGE lista ordenado por score. ZSCORE consulta score individual. Sorted sets mantêm ordem automática — ideais para rankings.
ZUNIONSTORE e ZDIFF
# Unir sorted sets (soma scores): ZUNIONSTORE resultado 2 set1 set2 ZUNIONSTORE resultado 2 set1 set2 WEIGHTS 2 1 # Interseção: ZINTERSTORE resultado 2 set1 set2 AGGREGATE MAX # Diferença (7+): ZDIFF 2 set1 set2 ZDIFFSTORE resultado 2 set1 set2
ZUNIONSTORE une somando scores. WEIGHTS multiplica scores por set. AGGREGATE define como combinar (SUM, MIN, MAX). ZDIFF (7+) mostra elementos só no primeiro.
Expiração e TTL
Definir expiração
EXPIRE chave 60 # expira em 60 segundos PEXPIRE chave 5000 # em 5000 milissegundos EXPIREAT chave 1700000000 # timestamp Unix PEXPIREAT chave 1700000000000 # timestamp ms # Ao criar: SET token "abc" EX 3600 # 1 hora
EXPIRE define TTL em segundos. PEXPIRE em milissegundos. EXPIREAT/PEXPIREAT usam timestamp absoluto. O Redis remove a chave automaticamente quando expira.
Sessões de utilizador
# Criar sessão
SET sessao:abc123 '{"user":"ana","role":"admin"}' EX 1800
# Renovar sessão (a cada request)
EXPIRE sessao:abc123 1800
# Verificar sessão
GET sessao:abc123 # nil = expirada
# Terminar sessão
DEL sessao:abc123Sessões em Redis: SET com EX 1800 (30 min). EXPIRE renova a cada request (sliding expiration). GET nil = sessão expirada. Muito mais rápido que BD relacional.
Consultar TTL
TTL chave # segundos restantes PTTL chave # milissegundos restantes # Retornos especiais: # -2 = chave não existe # -1 = chave existe mas sem expiração (permanente) # >0 = segundos restantes
TTL retorna segundos até expiração. PTTL em milissegundos (mais preciso). -2 = não existe, -1 = permanente. Essencial para verificar estado de cache e sessões.
Rate limiting
# Limite: 100 requests/min por IP INCR rate:192.168.1.1 EXPIRE rate:192.168.1.1 60 # só na primeira vez # Verificar: GET rate:192.168.1.1 # > 100 → bloquear # Alternativa com SET NX: SET rate:ip 1 NX EX 60 # janela fixa
INCR + EXPIRE implementa rate limiting por janela fixa. Cada IP tem contador que expira em 60s. Se contador > limite, rejeita. Atómico e eficiente. Padrão essencial em APIs.
Remover expiração
PERSIST chave # tornar permanente (remove TTL) # Verificar estado: TTL chave # -1 = permanente # Expirar imediatamente: EXPIRE chave 0 # ou DEL chave # GETEX (6.2+): ler e ajustar TTL GETEX chave PERSIST # ler + tornar permanente
PERSIST remove o TTL, tornando a chave permanente. EXPIRE 0 expira imediatamente. GETEX PERSIST (6.2+) faz leitura + persistência atomicamente.
Distributed lock
# Adquirir lock (só se não existir, expira em 10s)
SET lock:recurso "meu_id" NX EX 10
# Verificar se ainda é meu:
GET lock:recurso # "meu_id"?
# Libertar (com Lua para atomicidade):
EVAL "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 lock:recurso meu_idSET NX EX cria lock distribuído. NX garante exclusividade, EX evita deadlock se o processo morrer. Libertar com script Lua para verificar ownership. Base do algoritmo Redlock.
Cache com TTL
# Padrão cache-aside: SET cache:home "<html>..." EX 300 # 5 min GET cache:home # hit? # Se nil → recalcular e SET novamente # Invalidar: DEL cache:home # TTL variável por tipo: SET cache:perfil "..." EX 600 # 10 min SET cache:feed "..." EX 60 # 1 min
Padrão cache-aside: verifica cache, se miss recalcula e guarda com TTL. EX define validade. DEL invalida manualmente. TTLs diferentes por tipo de dado conforme frescura necessária.
Keyspace notifications
# Ativar notificações de expiração: CONFIG SET notify-keyspace-events Ex # Subscrever eventos de expiração: PSUBSCRIBE __keyevent@0__:expired # Quando uma chave expira, recebes: # mensagem: "nome_da_chave" # Útil para: sessões expiradas, # lembretes, agendamentos
Keyspace notifications emitem eventos quando chaves expiram ou são modificadas. Ativa com CONFIG SET notify-keyspace-events. PSUBSCRIBE ouve eventos. Útil para triggers e agendamentos.
Servidor e Admin
INFO (informação)
INFO # informação completa INFO memory # uso de memória INFO clients # clientes ligados INFO stats # estatísticas de operações INFO persistence # estado RDB/AOF INFO replication # estado de replicação DBSIZE # nº de chaves na BD atual
INFO retorna métricas do servidor por secção. memory mostra RAM usada. stats mostra ops/seg, hits, misses. DBSIZE conta chaves. Essencial para monitorização.
Eviction policies
CONFIG SET maxmemory 512mb CONFIG SET maxmemory-policy allkeys-lru # Políticas disponíveis: # noeviction → erro quando cheio (padrão) # allkeys-lru → remove menos usado (recomendado) # allkeys-lfu → remove menos frequente # volatile-lru → LRU só com TTL # volatile-ttl → menor TTL primeiro # allkeys-random → aleatório
Quando maxmemory é atingido, a política decide o que remover. allkeys-lru é o mais usado para cache. volatile-lru só remove chaves com TTL. noeviction retorna erro.
Limpar dados
DEL chave # eliminar uma chave (síncrono) UNLINK chave # eliminar assíncrono (4+) FLUSHDB # limpar BD atual FLUSHDB ASYNC # limpar em background FLUSHALL # limpar TODAS as BDs FLUSHALL ASYNC # todas em background # ⚠️ NUNCA FLUSHALL em produção!
DEL é síncrono (bloqueia). UNLINK é assíncrono (prefere em produção). FLUSHDB ASYNC limpa sem bloquear. FLUSHALL apaga tudo — extremamente perigoso em produção.
MONITOR e SLOWLOG
MONITOR # ver TODOS os comandos em tempo real # ⚠️ Impacto de performance! Só para debug. SLOWLOG GET 10 # últimos 10 comandos lentos SLOWLOG LEN # quantos registados SLOWLOG RESET # limpar log CONFIG SET slowlog-log-slower-than 10000 # >10ms
MONITOR mostra todos os comandos — pesado, só para debug pontual. SLOWLOG regista comandos acima do threshold. slowlog-log-slower-than em microssegundos. Essencial para encontrar bottlenecks.
Persistência (RDB e AOF)
SAVE # snapshot síncrono (bloqueia!) BGSAVE # snapshot em background LASTSAVE # timestamp do último save # RDB: snapshot pontual (dump.rdb) # AOF: log de todas as escritas (appendonly.aof) # Config AOF: CONFIG SET appendonly yes CONFIG SET appendfsync everysec
RDB = snapshots periódicos (rápido, perde dados entre saves). AOF = log de operações (durável, ficheiro maior). appendfsync everysec é o compromisso ideal. Usa ambos em produção.
MEMORY (análise de memória)
MEMORY USAGE chave # bytes de uma chave MEMORY USAGE chave SAMPLES 0 # exato (mais lento) MEMORY DOCTOR # diagnóstico MEMORY STATS # breakdown por categoria MEMORY MALLOC-STATS # stats do allocator INFO memory # resumo geral
MEMORY USAGE mostra bytes exatos de uma chave. MEMORY DOCTOR dá recomendações. MEMORY STATS mostra overhead, fragmentation. Útil para otimizar uso de RAM.
CONFIG (configuração)
CONFIG GET maxmemory # ver setting CONFIG SET maxmemory 256mb # alterar em runtime CONFIG GET save # regras de snapshot CONFIG SET maxmemory-policy allkeys-lru CONFIG REWRITE # persistir config em ficheiro # Sem CONFIG REWRITE, muda só em memória
CONFIG GET/SET ajusta parâmetros em runtime. maxmemory limita RAM. maxmemory-policy define eviction (LRU, LFU, random). CONFIG REWRITE persiste no redis.conf.
CLIENT (gestão de conexões)
CLIENT LIST # todas as conexões ativas CLIENT LIST TYPE normal # só clientes normais CLIENT GETNAME # nome desta conexão CLIENT SETNAME meu-worker # dar nome CLIENT KILL ID 42 # terminar conexão CLIENT PAUSE 5000 # pausar clientes 5s CLIENT NO-EVICT ON # proteger de eviction
CLIENT LIST mostra conexões com IP, idade, último comando. CLIENT KILL termina conexões problemáticas. CLIENT SETNAME facilita identificação. PAUSE para manutenção.
Pub/Sub, Streams e Truques
Pub/Sub
# Subscriber (fica à espera): SUBSCRIBE canal:noticias PSUBSCRIBE canal:* # padrão # Publisher: PUBLISH canal:noticias "Breaking: Redis 8 lançado!" # Mensagens NÃO são persistentes # Se subscriber offline, perde a mensagem
PUB/SUB é fire-and-forget — mensagens não são guardadas. SUBSCRIBE ouve, PUBLISH envia. PSUBSCRIBE aceita padrões. Para mensagens persistentes, usa Streams.
Lua scripting (EVAL)
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 minha_chave meu_valor
# Script com lógica:
EVAL "
local val = redis.call('GET', KEYS[1])
if tonumber(val) > tonumber(ARGV[1]) then
return redis.call('DECR', KEYS[1])
end
return 0
" 1 contador 5
EVALSHA sha1_hash 1 chave arg # script cacheadoEVAL executa scripts Lua no servidor — atómico e sem round-trips. KEYS[] são chaves, ARGV[] argumentos. EVALSHA reutiliza scripts cacheados. Ideal para lógica complexa atómica.
Streams (XADD/XREAD)
# Adicionar evento (ID automático): XADD eventos * tipo "login" user "ana" # Ler todos: XRANGE eventos - + XLEN eventos # Ler novos (a partir do último): XREAD STREAMS eventos $ # Com consumer group: XREADGROUP GROUP workers consumer1 STREAMS eventos >
Streams (Redis 5+) são filas persistentes com consumer groups. XADD adiciona, XREAD lê. XREADGROUP permite múltiplos consumidores. Substituto de Kafka para casos simples.
Convenções de nomes
# Padrão: objeto:campo ou tipo:id user:1:nome user:1:sessoes produto:100:stock cache:home:v2 rate:192.168.1.1 lock:pedido:42 # Separador: dois pontos (:) # Prefixos para organizar por domínio
Convenção: tipo:id:campo com separador :. Facilita organização e SCAN por padrão. Prefixos como cache:, rate:, lock: identificam o propósito. Evita chaves muito longas.
Transações (MULTI/EXEC)
MULTI # iniciar transação SET a "1" # enfileirado SET b "2" # enfileirado INCR contador # enfileirado EXEC # executar tudo atomicamente DISCARD # cancelar (antes de EXEC) # WATCH para optimistic locking: WATCH chave MULTI SET chave "novo" EXEC # falha se chave mudou
MULTI/EXEC agrupa comandos atomicamente — todos ou nenhum. DISCARD cancela. WATCH implementa optimistic locking: EXEC falha se a chave foi modificada por outro cliente.
Boas práticas de performance
# ✅ FAZER: # • SCAN em vez de KEYS * # • UNLINK em vez de DEL (chaves grandes) # • Pipelines para operações em lote # • TTL em todas as chaves de cache # • maxmemory + eviction policy # ❌ EVITAR: # • KEYS * em produção (bloqueia!) # • Valores > 10 KB sem necessidade # • FLUSHALL/FLUSHDB sem ASYNC # • MONITOR por tempo prolongado
Usa SCAN (não KEYS), UNLINK (não DEL), pipelines para lotes. Define sempre maxmemory e política de eviction. TTL em cache. Evita valores gigantes e comandos bloqueantes.
Pipelines
# Pipeline: enviar N comandos sem esperar resposta
# Reduz round-trips de rede drasticamente
# Via redis-cli:
redis-cli --pipe < comandos.txt
# Em código (exemplo Python):
pipe = r.pipeline()
pipe.set("a", "1")
pipe.set("b", "2")
pipe.incr("contador")
pipe.execute() # 1 round-trip em vez de 3Pipeline envia múltiplos comandos num batch sem esperar cada resposta. Reduz latência de rede de N round-trips para 1. Não é atómico (diferente de MULTI). 10-100x mais rápido em lote.
Redis vs Memcached
# Redis: # • Tipos ricos (hash, list, set, zset, stream) # • Persistência (RDB + AOF) # • Pub/Sub, Streams, Lua scripting # • Replicação master-replica # • Cluster nativo # Memcached: # • Só strings (chave-valor simples) # • Sem persistência # • Multi-thread (melhor em multi-core) # • Mais simples, menos features
Redis é mais versátil: tipos de dados ricos, persistência, scripting. Memcached é mais simples e multi-thread. Para cache simples com throughput extremo, Memcached. Para tudo o resto, Redis.