DevTools

Cheatsheet Redis

Base de dados em memória (chave-valor)

Volver a los lenguajes
Redis
64 tarjetas encontradas
Categorías:
Versiones:

Comandos Básicos


8 cards
Conexión (redis-cli)
redis-cli                    # conectar local (6379)
redis-cli -h 192.168.1.10   # host remoto
redis-cli -p 6380           # puerto custom
redis-cli -a mi_clave       # con password
redis-cli -n 2              # base de datos 2
redis-cli --tls             # con TLS

redis-cli es el cliente de línea de comandos. -h define el host, -p el puerto, -a la password. -n selecciona la base de datos (0-15 por defecto).

Seleccionar base de datos
SELECT 0        # base de datos 0 (por defecto)
SELECT 1        # base de datos 1
DBSIZE          # nº de claves en la BD actual
MOVE clave 1    # mover clave a la BD 1
FLUSHDB         # limpiar la BD actual (¡CUIDADO!)

Redis tiene 16 bases de datos lógicas (0-15) por defecto. SELECT cambia entre ellas. Están aisladas pero comparten memoria. En producción, prefiere instancias separadas o namespaces con prefijos.

Primeros comandos
PING              # responde PONG
SET nombre "Ana"  # guardar un valor
GET nombre        # leer → "Ana"
DEL nombre        # eliminar clave
EXISTS nombre     # ¿la clave existe? (1/0)
TYPE nombre       # tipo del valor

PING prueba la conexión. SET guarda, GET lee, DEL elimina. EXISTS verifica la presencia. TYPE devuelve el tipo: string, list, hash, set, zset.

SCAN (iteración segura)
SCAN 0 MATCH user:* COUNT 100
# → [cursor, [claves...]]

SCAN 17 MATCH user:* COUNT 100
# continúa desde el cursor 17

# Cursor 0 = terminó
# HSCAN, SSCAN, ZSCAN para tipos compuestos

SCAN itera claves sin bloquear el servidor. Devuelve un cursor y un lote. Repite hasta cursor = 0. HSCAN para hashes, SSCAN para sets, ZSCAN para sorted sets.

Gestionar claves
KEYS user:*        # claves que coinciden con un patrón
SCAN 0 MATCH user:* COUNT 100  # iterativo (seguro)
TYPE clave         # tipo del valor
RENAME old new     # renombrar clave
RANDOMKEY          # clave aleatoria
OBJECT ENCODING clave  # representación interna

KEYS devuelve todas las claves que coinciden con el patrón — ¡bloquea en producción! Usa SCAN como alternativa iterativa y segura. OBJECT ENCODING muestra la estructura interna.

DEL y UNLINK
DEL clave1 clave2 clave3   # síncrono (bloquea)
UNLINK clave1 clave2       # asíncrono (background)

# UNLINK libera memoria en un thread separado
# Ideal para claves grandes (listas, hashes)
# Devuelve el nº de claves eliminadas

DEL elimina síncronamente — puede bloquear con claves grandes. UNLINK (Redis 4+) elimina en background sin bloquear. Prefiere UNLINK en producción para claves con muchos elementos.

Tipos de datos
string   # texto o número (SET/GET)
list     # lista ordenada (LPUSH/RPUSH)
hash     # objeto con campos (HSET/HGET)
set      # conjunto único (SADD)
zset     # conjunto ordenado por score (ZADD)
stream   # flujo de eventos (XADD)
bitmap   # bits individuales (SETBIT)
hyperloglog  # conteo aproximado (PFADD)

Redis tiene 8 tipos de datos. string es el más versátil. hash modela objetos. zset es ideal para rankings. stream para colas persistentes. Cada tipo tiene comandos específicos.

COPY y OBJECT
COPY origen destino          # copiar clave
COPY origen destino DB 1     # copiar a otra BD
COPY origen destino REPLACE  # sobrescribir destino

OBJECT ENCODING clave   # int, embstr, raw, listpack...
OBJECT IDLETIME clave   # segundos sin acceso
OBJECT FREQ clave       # frecuencia (LFU)

COPY (Redis 6.2+) duplica una clave. OBJECT ENCODING muestra la representación interna. IDLETIME indica cuánto tiempo lleva sin ser accedida. Útil para debugging y optimización.

Strings


8 cards
SET y GET
SET ciudad "Lisbon"
GET ciudad              # "Lisbon"

# Opciones de SET:
SET token "abc" EX 60   # expira en 60s
SET clave "v" NX        # solo si NO existe
SET clave "v" XX        # solo si existe
SET clave "v" KEEPTTL   # mantener el TTL existente

SET guarda un valor. GET lo lee. Opciones: EX (segundos), PX (ms), NX (crear solo), XX (actualizar solo), KEEPTTL preserva la expiración.

SET con expiración
SET sesion "xyz" EX 3600      # 1 hora
SET temp "v" PX 5000          # 5000 milisegundos
SET lock "1" NX EX 10         # lock de 10s (solo si no existe)
SET cache "html" EXAT 1700000000  # timestamp Unix

# EX = segundos, PX = milisegundos
# EXAT = timestamp absoluto, PXAT = ms absoluto

Combina SET con un TTL en una operación atómica. NX EX es el patrón para distributed locks. EXAT define la expiración por un 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 precio 1.5  # suma decimal

# Si la clave no existe, empieza en 0
INCR nueva_clave    # 1

INCR/DECR son operaciones atómicas — seguras en concurrencia. Ideales para contadores, rate limiting e IDs secuenciales. INCRBY suma N. INCRBYFLOAT para decimales.

Bitmaps
SETBIT presencia 0 1    # bit 0 = 1
SETBIT presencia 1 0    # bit 1 = 0
GETBIT presencia 0      # 1
BITCOUNT presencia      # total de bits a 1
BITPOS presencia 1      # posición del primer 1
BITOP AND resultado set1 set2  # operación entre bitmaps

Los Bitmaps operan a nivel de bit sobre strings. Ultra-compactos para flags (presencia, login diario). BITCOUNT cuenta los bits activos. 1 MB almacena ~8 millones de flags. Ideal para analytics.

MSET y MGET (lote)
MSET a "1" b "2" c "3"    # guardar varias
MGET a b c                 # ["1", "2", "3"]

MSETNX a "1" b "2"        # solo si NINGUNA existe

# MGET devuelve nil para claves inexistentes
MGET a inexistente c      # ["1", nil, "3"]

MSET/MGET operan sobre múltiples claves en una llamada — reduce round-trips. MSETNX es atómico: solo define si ninguna clave existe. Más eficiente que SET/GET individuales.

HyperLogLog
PFADD visitas "user1" "user2" "user3"
PFADD visitas "user2" "user4"
PFCOUNT visitas          # 4 (únicos aproximados)

PFMERGE total set1 set2  # unir conteos

# Error estándar: ~0.81%
# Usa solo 12 KB de memoria (vs millones en un SET)

HyperLogLog cuenta elementos únicos con memoria mínima (12 KB). Error ~0.81%. Ideal para contar visitantes únicos, UVs. PFADD añade, PFCOUNT estima, PFMERGE une.

Manipular strings
APPEND nombre " Silva"   # añadir al final
STRLEN nombre            # longitud
SETRANGE nombre 0 "X"    # reemplazar una posición
GETRANGE nombre 0 3      # substring
GETDEL nombre            # leer y borrar (6.2+)
GETSET nombre "nuevo"    # intercambiar y devolver el antiguo

APPEND concatena. STRLEN da la longitud. GETRANGE extrae una substring. GETDEL (6.2+) lee y elimina atómicamente. Strings hasta 512 MB de tamaño máximo.

GETEX y GETDEL
# Leer y definir TTL atómicamente (6.2+)
GETEX clave EX 60      # leer + expirar en 60s
GETEX clave PERSIST    # leer + quitar TTL

# Leer y borrar atómicamente (6.2+)
GETDEL clave           # devuelve el valor y lo elimina

# Útil para one-time tokens:
SET otp "1234" EX 300
GETDEL otp             # usa una vez y borra

GETEX (6.2+) lee y ajusta el TTL en una operación. GETDEL lee y elimina atómicamente — ideal para tokens de un solo uso. Evita race conditions entre GET y DEL/EXPIRE separados.

Listas


8 cards
Añadir elementos
LPUSH cola "a"         # inicio (izquierda)
RPUSH cola "b"         # fin (derecha)
LPUSH cola a b c       # varios a la vez
LINSERT cola BEFORE "b" "x"  # insertar antes

LLEN cola              # longitud
LINDEX cola 0          # elemento por índice

LPUSH inserta a la izquierda, RPUSH a la derecha. LINSERT inserta antes/después de un valor. LLEN da la longitud. Las listas mantienen el orden de inserción y aceptan duplicados.

Blocking pop (BLPOP/BRPOP)
# Espera hasta que haya un elemento o timeout
BLPOP cola 30       # timeout 30s
BRPOP cola 0        # espera infinita

# Múltiples colas (prioridad):
BLPOP alta media baja 30
# verifica "alta" primero

# Devuelve nil si el timeout expira

BLPOP/BRPOP bloquean hasta que haya datos. Ideales para workers que esperan tareas. Timeout 0 = espera infinita. Múltiples listas = prioridad (la primera con datos se consume).

Leer elementos
LRANGE cola 0 -1     # todos los elementos
LRANGE cola 0 9      # primeros 10
LRANGE cola -5 -1    # últimos 5

LPOP cola            # eliminar y devolver del inicio
RPOP cola            # eliminar y devolver del fin
LPOP cola 3          # eliminar 3 del inicio (6.2+)
LMPOP 2 cola1 cola2 LEFT  # pop de múltiples listas

LRANGE lee sin eliminar (0 = primero, -1 = último). LPOP/RPOP eliminan y devuelven. Desde 6.2+, LPOP N elimina múltiples. LMPOP opera sobre varias listas.

LSET y LREM
# Actualizar por índice
LSET cola 0 "nuevo_valor"

# Eliminar por valor
LREM cola 2 "elemento"    # elimina 2 ocurrencias
LREM cola 0 "elemento"    # elimina TODAS
LREM cola -1 "elemento"   # elimina 1 del fin

# Trim (mantener solo N elementos)
LTRIM cola 0 99           # mantener los primeros 100

LSET actualiza por índice. LREM elimina por valor (count positivo = del inicio, negativo = del fin, 0 = todos). LTRIM trunca la lista — útil para limitar su tamaño.

Cola (FIFO)
# Producer: añadir al final
RPUSH tareas "job1"
RPUSH tareas "job2"
RPUSH tareas "job3"

# Consumer: eliminar del inicio
LPOP tareas    # "job1" (primero en entrar)
LPOP tareas    # "job2"

# RPUSH + LPOP = FIFO (First In, First Out)

Patrón FIFO: RPUSH para producir, LPOP para consumir. El primero en entrar es el primero en salir. Base para colas de mensajes y task queues simples.

RPOPLPUSH (mover entre listas)
# Mover un elemento de una lista a otra
RPOPLPUSH origen destino

# Caso de uso: cola de procesamiento
RPUSH tareas "job1"
RPOPLPUSH tareas en_proceso
# ... procesar ...
LREM en_proceso 1 "job1"

# LMOVE (6.2+, más flexible):
LMOVE origen destino RIGHT LEFT

RPOPLPUSH mueve atómicamente del fin de una lista al inicio de otra. Patrón de cola fiable: un item permanece en "processing" hasta la confirmación. LMOVE (6.2+) permite elegir los lados.

Pila (LIFO)
# Push: añadir al inicio
LPUSH pila "a"
LPUSH pila "b"
LPUSH pila "c"

# Pop: eliminar del inicio
LPOP pila    # "c" (último en entrar)
LPOP pila    # "b"

# LPUSH + LPOP = LIFO (Last In, First Out)

Patrón LIFO: LPUSH + LPOP (mismo lado). El último en entrar es el primero en salir. Útil para stacks, undo/redo, historial de navegación.

Lista como log circular
# Mantener solo los últimos 1000 eventos
RPUSH log:evento "error: timeout"
LTRIM log:evento -1000 -1

# Leer los últimos 10
LRANGE log:evento -10 -1

# Patrón: RPUSH + LTRIM = tamaño fijo
# Nunca crece más allá del límite

Combina RPUSH + LTRIM para un log de tamaño fijo. LTRIM -N -1 mantiene solo los últimos N. Eficiente en memoria. Ideal para activity feeds, logs recientes e historial limitado.

Hashes


8 cards
Crear hash (HSET)
HSET user:1 nombre "Ana" edad 30 ciudad "Porto"

# O campo a campo:
HSET user:1 nombre "Ana"
HSET user:1 edad 30

# Solo si no existe:
HSETNX user:1 email "ana@mail.com"

HGET user:1 nombre    # "Ana"

HSET define campos en un hash. Acepta múltiples pares campo-valor. HSETNX solo define si el campo no existe. HGET lee un campo. Ideal para modelar objetos.

HSCAN (iterar hash grande)
HSCAN user:1 0 MATCH nombre* COUNT 100
# → [cursor, [campo, valor, ...]]

# Iterar todos los campos:
HSCAN user:1 0 COUNT 1000
# repetir con el cursor devuelto hasta 0

# Esencial para hashes con miles de campos

HSCAN itera los campos de un hash sin bloquear. Esencial para hashes grandes (miles de campos). Devuelve cursor + lote. Repetir hasta cursor = 0. Nunca uses HGETALL en hashes enormes.

Leer hash
HGETALL user:1       # todos los campos y valores
HGET user:1 nombre   # un campo
HMGET user:1 nombre edad ciudad  # varios campos
HKEYS user:1         # nombres de los campos
HVALS user:1         # solo los valores
HLEN user:1          # nº de campos
HSTRLEN user:1 nombre  # longitud del valor

HGETALL devuelve todo (cuidado con hashes grandes). HMGET campos específicos. HKEYS/HVALS separan nombres y valores. HLEN cuenta campos.

HRANDFIELD (6.2+)
# Campo aleatorio
HRANDFIELD user:1

# 3 campos aleatorios (sin repetición)
HRANDFIELD user:1 3

# Con valores:
HRANDFIELD user:1 3 WITHVALUES

# Con repetición (count negativo):
HRANDFIELD user:1 -5

HRANDFIELD (6.2+) devuelve campos aleatorios. Count positivo = sin repetición, negativo = con repetición. WITHVALUES incluye los valores. Útil para sorteos y muestras.

Actualizar y eliminar campos
HSET user:1 edad 31           # actualizar
HINCRBY user:1 edad 1         # incrementar (32)
HINCRBYFLOAT user:1 saldo 9.5 # decimal
HDEL user:1 ciudad            # eliminar campo
HEXISTS user:1 nombre         # ¿el campo existe? (1/0)
HDEL user:1 campo1 campo2     # eliminar varios

HSET sobrescribe el campo. HINCRBY incrementa atómicamente. HDEL elimina campos. HEXISTS verifica la presencia. Las operaciones sobre campos individuales son eficientes.

Hash vs String (cuándo usar)
# Hash: objeto con múltiples campos
HSET user:1 nombre "Ana" edad 30 email "a@b.com"
# → update parcial: HSET user:1 edad 31

# Strings: valores simples o serializados
SET user:1:nombre "Ana"
SET user:1:json '{"nombre":"Ana","edad":30}'
# → update total: reescribir el JSON entero

Usa un hash para objetos con updates parciales frecuentes. Usa una string para valores simples o datos siempre leídos/escritos juntos. Un hash ahorra memoria con muchos campos pequeños.

Hash como objeto (modelado)
# Modelar un producto
HSET producto:100 nombre "TV 4K" precio 500 stock 10 activo 1

# Operaciones típicas:
HGETALL producto:100
HINCRBY producto:100 stock -1    # vender
HSET producto:100 activo 0       # desactivar
HMGET producto:100 nombre precio    # campos específicos

Los hashes son perfectos para modelar objetos: cada campo es una propiedad. Convención: tipo:id como clave. Más eficiente que múltiples strings. Soporta updates parciales sin reescribir todo.

Hash con TTL (7.4+)
# TTL por campo (Redis 7.4+)
HSET sesion:abc user "ana" EX 3600
HSET sesion:abc token "xyz" EX 600

HEXPIRE sesion:abc 300 FIELDS user token
HTTL sesion:abc FIELDS user
HPERSIST sesion:abc FIELDS token

# Antes de 7.4: TTL solo en la clave entera
EXPIRE sesion:abc 3600

Desde Redis 7.4+, los campos de un hash pueden tener un TTL individual con HSET ... EX y HEXPIRE. Antes, solo la clave entera expiraba. Útil para sesiones con campos de validez diferente.

Sets e Sorted Sets


8 cards
Sets (conjuntos únicos)
SADD tags "php" "redis" "docker"
SMEMBERS tags          # todos los miembros
SISMEMBER tags "php"   # ¿pertenece? (1/0)
SMISMEMBER tags "php" "go"  # múltiples (6.2+)
SCARD tags             # nº de miembros
SREM tags "php"        # eliminar miembro

SADD añade (ignora duplicados). SMEMBERS lista todo. SISMEMBER verifica la pertenencia en O(1). SCARD cuenta. Los sets no tienen orden y no aceptan repetidos.

Rankings y leaderboards
ZREVRANGE ranking 0 2 WITHSCORES  # top 3 (desc)
ZRANK ranking "ana"               # posición (asc, 0-based)
ZREVRANK ranking "ana"            # posición (desc)
ZINCRBY ranking 5 "ana"           # +5 puntos
ZCOUNT ranking 90 100             # cuántos entre 90-100
ZREMRANGEBYRANK ranking 0 9       # eliminar bottom 10

ZREVRANGE = top N (mayor score primero). ZRANK/ZREVRANK dan la posición. ZINCRBY incrementa el score. Un patrón perfecto para leaderboards en tiempo real.

Operaciones entre sets
SINTER a b          # intersección (elementos comunes)
SUNION a b          # unión (todos sin duplicados)
SDIFF a b           # diferencia (en a pero no en b)

# Guardar el resultado:
SINTERSTORE resultado a b
SUNIONSTORE resultado a b

# Cardinalidad de la intersección (sin guardar):
SINTERCARD 2 a b LIMIT 10

SINTER = elementos comunes. SUNION = todos combinados. SDIFF = solo en el primero. Las versiones *STORE guardan el resultado. SINTERCARD (7+) cuenta sin 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        # eliminar ≤50
ZRANGEBYSCORE ranking -inf +inf      # todos

# Con paginación:
ZRANGEBYSCORE ranking 0 100 LIMIT 0 10

ZRANGEBYSCORE filtra por intervalo de score. ( lo hace exclusivo. -inf/+inf para límites abiertos. LIMIT offset count pagina. Útil para filtros por precio, tiempo, prioridad.

SPOP y SRANDMEMBER
SPOP sorteo             # eliminar y devolver aleatorio
SPOP sorteo 3           # eliminar 3 aleatorios
SRANDMEMBER sorteo      # ver aleatorio (sin eliminar)
SRANDMEMBER sorteo 5    # 5 aleatorios (sin eliminar)

# SMOVE: mover entre sets
SMOVE origen destino "elemento"

SPOP elimina aleatoriamente (sorteos, loterías). SRANDMEMBER ve sin eliminar (muestras). SMOVE transfiere entre sets atómicamente. Todos O(1) o O(N) según el count.

ZRANGEBYLEX (lexicográfico)
# Todos con el mismo score → ordenación alfabética
ZADD nombres 0 "ana" 0 "bruno" 0 "carla" 0 "david"

ZRANGEBYLEX nombres [ana [carla     # ana a carla
ZRANGEBYLEX nombres (ana +          # después de "ana"
ZREMRANGEBYLEX nombres [a [b        # eliminar a-b
ZLEXCOUNT nombres [a [z             # contar en el rango

Cuando todos los scores son iguales, ZRANGEBYLEX ordena lexicográficamente. [ = inclusivo, ( = exclusivo. Útil para autocomplete y diccionarios ordenados.

Sorted Sets (ZADD)
ZADD ranking 100 "ana" 85 "juan" 92 "maria"

ZRANGE ranking 0 -1 WITHSCORES   # todos con scores
ZSCORE ranking "ana"             # 100
ZCARD ranking                    # nº de miembros
ZMSCORE ranking "ana" "juan"      # múltiples scores
ZADD ranking 95 "ana"            # actualizar score

ZADD añade con un score (o actualiza). ZRANGE lista ordenado por score. ZSCORE consulta un score individual. Los sorted sets mantienen un orden automático — ideales para rankings.

ZUNIONSTORE y ZDIFF
# Unir sorted sets (suma scores):
ZUNIONSTORE resultado 2 set1 set2
ZUNIONSTORE resultado 2 set1 set2 WEIGHTS 2 1

# Intersección:
ZINTERSTORE resultado 2 set1 set2 AGGREGATE MAX

# Diferencia (7+):
ZDIFF 2 set1 set2
ZDIFFSTORE resultado 2 set1 set2

ZUNIONSTORE une sumando scores. WEIGHTS multiplica los scores por set. AGGREGATE define cómo combinar (SUM, MIN, MAX). ZDIFF (7+) muestra los elementos solo en el primero.

Expiração e TTL


8 cards
Definir expiración
EXPIRE clave 60           # expira en 60 segundos
PEXPIRE clave 5000        # en 5000 milisegundos
EXPIREAT clave 1700000000 # timestamp Unix
PEXPIREAT clave 1700000000000  # timestamp ms

# Al crear:
SET token "abc" EX 3600   # 1 hora

EXPIRE define un TTL en segundos. PEXPIRE en milisegundos. EXPIREAT/PEXPIREAT usan un timestamp absoluto. Redis elimina la clave automáticamente cuando expira.

Sesiones de usuario
# Crear sesión
SET sesion:abc123 '{"user":"ana","role":"admin"}' EX 1800

# Renovar sesión (en cada request)
EXPIRE sesion:abc123 1800

# Verificar sesión
GET sesion:abc123    # nil = expirada

# Terminar sesión
DEL sesion:abc123

Sesiones en Redis: SET con EX 1800 (30 min). EXPIRE renueva en cada request (sliding expiration). GET nil = sesión expirada. Mucho más rápido que una BD relacional.

Consultar TTL
TTL clave       # segundos restantes
PTTL clave      # milisegundos restantes

# Retornos especiales:
# -2 = la clave no existe
# -1 = la clave existe pero sin expiración (permanente)
# >0 = segundos restantes

TTL devuelve los segundos hasta la expiración. PTTL en milisegundos (más preciso). -2 = no existe, -1 = permanente. Esencial para verificar el estado de cache y sesiones.

Rate limiting
# Límite: 100 requests/min por IP
INCR rate:192.168.1.1
EXPIRE rate:192.168.1.1 60    # solo en la primera vez

# Verificar:
GET rate:192.168.1.1         # > 100 → bloquear

# Alternativa con SET NX:
SET rate:ip 1 NX EX 60       # ventana fija

INCR + EXPIRE implementa rate limiting por ventana fija. Cada IP tiene un contador que expira en 60s. Si el contador > límite, rechaza. Atómico y eficiente. Un patrón esencial en APIs.

Quitar expiración
PERSIST clave      # hacer permanente (quita TTL)

# Verificar el estado:
TTL clave          # -1 = permanente

# Expirar inmediatamente:
EXPIRE clave 0     # o DEL clave

# GETEX (6.2+): leer y ajustar TTL
GETEX clave PERSIST   # leer + hacer permanente

PERSIST quita el TTL, haciendo la clave permanente. EXPIRE 0 expira inmediatamente. GETEX PERSIST (6.2+) hace lectura + persistencia atómicamente.

Distributed lock
# Adquirir lock (solo si no existe, expira en 10s)
SET lock:recurso "mi_id" NX EX 10

# Verificar si aún es mío:
GET lock:recurso    # ¿"mi_id"?

# Liberar (con Lua para atomicidad):
EVAL "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 lock:recurso mi_id

SET NX EX crea un lock distribuido. NX garantiza la exclusividad, EX evita un deadlock si el proceso muere. Libera con un script Lua para verificar el ownership. La base del algoritmo Redlock.

Cache con TTL
# Patrón cache-aside:
SET cache:home "<html>..." EX 300    # 5 min
GET cache:home                        # ¿hit?
# Si nil → recalcular y SET de nuevo

# Invalidar:
DEL cache:home

# TTL variable por tipo:
SET cache:perfil "..." EX 600        # 10 min
SET cache:feed "..." EX 60           # 1 min

Patrón cache-aside: verifica la cache, si hay miss recalcula y guarda con un TTL. EX define la validez. DEL invalida manualmente. TTLs diferentes por tipo de dato según la frescura necesaria.

Keyspace notifications
# Activar notificaciones de expiración:
CONFIG SET notify-keyspace-events Ex

# Suscribir eventos de expiración:
PSUBSCRIBE __keyevent@0__:expired

# Cuando una clave expira, recibes:
# mensaje: "nombre_de_la_clave"

# Útil para: sesiones expiradas,
# recordatorios, agendamientos

Las Keyspace notifications emiten eventos cuando las claves expiran o se modifican. Actívalas con CONFIG SET notify-keyspace-events. PSUBSCRIBE escucha los eventos. Útil para triggers y agendamientos.

Servidor e Admin


8 cards
INFO (información)
INFO                  # información completa
INFO memory           # uso de memoria
INFO clients          # clientes conectados
INFO stats            # estadísticas de operaciones
INFO persistence      # estado RDB/AOF
INFO replication      # estado de replicación
DBSIZE                # nº de claves en la BD actual

INFO devuelve métricas del servidor por sección. memory muestra la RAM usada. stats muestra ops/seg, hits, misses. DBSIZE cuenta las claves. Esencial para monitorización.

Eviction policies
CONFIG SET maxmemory 512mb
CONFIG SET maxmemory-policy allkeys-lru

# Políticas disponibles:
# noeviction    → error cuando está lleno (por defecto)
# allkeys-lru   → elimina el menos usado (recomendado)
# allkeys-lfu   → elimina el menos frecuente
# volatile-lru  → LRU solo con TTL
# volatile-ttl  → menor TTL primero
# allkeys-random → aleatorio

Cuando se alcanza maxmemory, la política decide qué eliminar. allkeys-lru es la más usada para cache. volatile-lru solo elimina claves con TTL. noeviction devuelve un error.

Limpiar datos
DEL clave             # eliminar una clave (síncrono)
UNLINK clave          # eliminar asíncrono (4+)
FLUSHDB               # limpiar la BD actual
FLUSHDB ASYNC         # limpiar en background
FLUSHALL              # limpiar TODAS las BDs
FLUSHALL ASYNC        # todas en background

# ⚠️ ¡NUNCA FLUSHALL en producción!

DEL es síncrono (bloquea). UNLINK es asíncrono (prefiérelo en producción). FLUSHDB ASYNC limpia sin bloquear. FLUSHALL elimina todo — extremadamente peligroso en producción.

MONITOR y SLOWLOG
MONITOR                    # ver TODOS los comandos en tiempo real
# ⚠️ ¡Impacto de performance! Solo para debug.

SLOWLOG GET 10             # últimos 10 comandos lentos
SLOWLOG LEN                # cuántos registrados
SLOWLOG RESET              # limpiar el log

CONFIG SET slowlog-log-slower-than 10000  # >10ms

MONITOR muestra todos los comandos — pesado, solo para debug puntual. SLOWLOG registra los comandos por encima del threshold. slowlog-log-slower-than en microsegundos. Esencial para encontrar bottlenecks.

Persistencia (RDB y AOF)
SAVE              # snapshot síncrono (¡bloquea!)
BGSAVE            # snapshot en background
LASTSAVE          # timestamp del último save

# RDB: snapshot puntual (dump.rdb)
# AOF: log de todas las escrituras (appendonly.aof)

# Config AOF:
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec

RDB = snapshots periódicos (rápido, pierde datos entre saves). AOF = log de operaciones (durable, fichero mayor). appendfsync everysec es el compromiso ideal. Usa ambos en producción.

MEMORY (análisis de memoria)
MEMORY USAGE clave          # bytes de una clave
MEMORY USAGE clave SAMPLES 0  # exacto (más lento)
MEMORY DOCTOR               # diagnóstico
MEMORY STATS                # breakdown por categoría
MEMORY MALLOC-STATS         # stats del allocator

INFO memory                 # resumen general

MEMORY USAGE muestra los bytes exactos de una clave. MEMORY DOCTOR da recomendaciones. MEMORY STATS muestra overhead, fragmentation. Útil para optimizar el uso de RAM.

CONFIG (configuración)
CONFIG GET maxmemory          # ver un setting
CONFIG SET maxmemory 256mb    # cambiar en runtime
CONFIG GET save               # reglas de snapshot
CONFIG SET maxmemory-policy allkeys-lru
CONFIG REWRITE                # persistir config a fichero

# Sin CONFIG REWRITE, cambia solo en memoria

CONFIG GET/SET ajusta parámetros en runtime. maxmemory limita la RAM. maxmemory-policy define el eviction (LRU, LFU, random). CONFIG REWRITE persiste en redis.conf.

CLIENT (gestión de conexiones)
CLIENT LIST                 # todas las conexiones activas
CLIENT LIST TYPE normal     # solo clientes normales
CLIENT GETNAME              # nombre de esta conexión
CLIENT SETNAME mi-worker    # dar un nombre
CLIENT KILL ID 42           # terminar una conexión
CLIENT PAUSE 5000           # pausar clientes 5s
CLIENT NO-EVICT ON          # proteger de eviction

CLIENT LIST muestra las conexiones con IP, edad, último comando. CLIENT KILL termina conexiones problemáticas. CLIENT SETNAME facilita la identificación. PAUSE para mantenimiento.

Pub/Sub, Streams e Truques


8 cards
Pub/Sub
# Subscriber (queda a la espera):
SUBSCRIBE canal:noticias
PSUBSCRIBE canal:*          # patrón

# Publisher:
PUBLISH canal:noticias "Breaking: ¡Redis 8 lanzado!"

# Los mensajes NO son persistentes
# Si el subscriber está offline, pierde el mensaje

PUB/SUB es fire-and-forget — los mensajes no se guardan. SUBSCRIBE escucha, PUBLISH envía. PSUBSCRIBE acepta patrones. Para mensajes persistentes, usa Streams.

Lua scripting (EVAL)
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mi_clave mi_valor

# Script con 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 clave arg   # script cacheado

EVAL ejecuta scripts Lua en el servidor — atómico y sin round-trips. KEYS[] son claves, ARGV[] argumentos. EVALSHA reutiliza scripts cacheados. Ideal para lógica compleja atómica.

Streams (XADD/XREAD)
# Añadir un evento (ID automático):
XADD eventos * tipo "login" user "ana"

# Leer todos:
XRANGE eventos - +
XLEN eventos

# Leer nuevos (a partir del último):
XREAD STREAMS eventos $

# Con un consumer group:
XREADGROUP GROUP workers consumer1 STREAMS eventos >

Streams (Redis 5+) son colas persistentes con consumer groups. XADD añade, XREAD lee. XREADGROUP permite múltiples consumidores. Un sustituto de Kafka para casos simples.

Convenciones de nombres
# Patrón: objeto:campo o tipo:id
user:1:nombre
user:1:sesiones
producto:100:stock
cache:home:v2
rate:192.168.1.1
lock:pedido:42

# Separador: dos puntos (:)
# Prefijos para organizar por dominio

Convención: tipo:id:campo con el separador :. Facilita la organización y el SCAN por patrón. Prefijos como cache:, rate:, lock: identifican el propósito. Evita claves muy largas.

Transacciones (MULTI/EXEC)
MULTI             # iniciar transacción
SET a "1"         # encolado
SET b "2"         # encolado
INCR contador     # encolado
EXEC              # ejecutar todo atómicamente

DISCARD           # cancelar (antes de EXEC)

# WATCH para optimistic locking:
WATCH clave
MULTI
SET clave "nuevo"
EXEC              # falla si la clave cambió

MULTI/EXEC agrupa comandos atómicamente — todos o ninguno. DISCARD cancela. WATCH implementa optimistic locking: EXEC falla si la clave fue modificada por otro cliente.

Buenas prácticas de performance
# ✅ HACER:
# • SCAN en vez de KEYS *
# • UNLINK en vez de DEL (claves grandes)
# • Pipelines para operaciones en lote
# • TTL en todas las claves de cache
# • maxmemory + eviction policy

# ❌ EVITAR:
# • KEYS * en producción (¡bloquea!)
# • Valores > 10 KB sin necesidad
# • FLUSHALL/FLUSHDB sin ASYNC
# • MONITOR por tiempo prolongado

Usa SCAN (no KEYS), UNLINK (no DEL), pipelines para lotes. Define siempre maxmemory y una política de eviction. TTL en cache. Evita valores gigantes y comandos bloqueantes.

Pipelines
# Pipeline: enviar N comandos sin esperar respuesta
# Reduce drásticamente los round-trips de red

# Vía redis-cli:
redis-cli --pipe < comandos.txt

# En código (ejemplo Python):
pipe = r.pipeline()
pipe.set("a", "1")
pipe.set("b", "2")
pipe.incr("contador")
pipe.execute()    # 1 round-trip en vez de 3

Pipeline envía múltiples comandos en un batch sin esperar cada respuesta. Reduce la latencia de red de N round-trips a 1. No es atómico (a diferencia de MULTI). 10-100x más rápido en lote.

Redis vs Memcached
# Redis:
# • Tipos ricos (hash, list, set, zset, stream)
# • Persistencia (RDB + AOF)
# • Pub/Sub, Streams, Lua scripting
# • Replicación master-replica
# • Cluster nativo

# Memcached:
# • Solo strings (clave-valor simple)
# • Sin persistencia
# • Multi-thread (mejor en multi-core)
# • Más simple, menos features

Redis es más versátil: tipos de datos ricos, persistencia, scripting. Memcached es más simple y multi-thread. Para cache simple con throughput extremo, Memcached. Para todo lo demás, Redis.