Cheatsheet Redis
Base de dados em memória (chave-valor)
Redis
Comandos Básicos
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
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
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
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 enteroUsa 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
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
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:abc123Sesiones 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_idSET 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
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
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 cacheadoEVAL 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 3Pipeline 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.