Dominando GET y SET de Redis: Operaciones Básicas de Datos
Domina los fundamentos de la gestión de datos en Redis con esta guía completa de los comandos `GET` y `SET`. Aprende el almacenamiento y recuperación básico de cadenas, y explora opciones avanzadas esenciales como el establecimiento atómico (`NX`/`XX`) y la caducidad integrada de claves (`EX`/`PX`). Descubre cómo estos comandos fundamentales son cruciales para construir capas de caché de alto rendimiento.
Dominando GET y SET de Redis: Operaciones Básicas de Datos
Redis GET y SET parecen casi demasiado simples. Escribir un valor. Leer un valor. En aplicaciones reales, esos dos comandos están detrás de sesiones de inicio de sesión, flags de funcionalidad, límites de tasa, entradas de caché, bloqueos de corta duración y atajos de "por favor no consultes la base de datos otra vez".
Los detalles importan porque Redis hace exactamente lo que le pides. Si sobrescribes una clave por accidente, no preguntará si tenías la intención. Si olvidas una caducidad en datos de caché, puede vivir más que la fuente de datos. Si tratas una clave faltante igual que una cadena vacía, tu aplicación puede tomar la decisión equivocada.
El Modelo Clave-Valor de Redis
Antes de sumergirnos en los comandos, es importante recordar que Redis opera en un modelo simple de almacén clave-valor. Cada pieza de datos (el valor) se accede usando un identificador único (la clave). Las claves son cadenas, y los valores pueden ser varios tipos de datos (cadenas, listas, conjuntos, hashes, etc.). SET y GET se ocupan principalmente del tipo de datos String, que es el tipo más básico y frecuentemente utilizado en Redis.
1. Estableciendo Datos: El Comando SET
El comando SET se utiliza para asignar un valor a una clave. Si la clave ya contiene datos, el comando SET sobrescribirá el valor existente. Su sintaxis básica es sencilla.
Sintaxis y Uso Básico
La forma más simple requiere solo la clave y el valor:
SET clave valor
Ejemplo: almacenar el nombre para mostrar de un usuario:
127.0.0.1:6379> SET usuario:100:nombre "Alicia García"
OK
127.0.0.1:6379> GET usuario:100:nombre
"Alicia García"
Opciones Avanzadas de SET: NX, XX y Caducidad
El poder de SET proviene de sus argumentos opcionales, que permiten el establecimiento condicional atómico y la gestión del tiempo de vida (TTL). Estas opciones son vitales para implementar bloqueos y cachés correctamente.
Establecimiento Condicional: NX y XX
Estas opciones controlan cuándo ocurre una operación de establecimiento, evitando sobrescrituras accidentales o asegurando que una sobrescritura ocurra solo si la clave existe.
NX(No Existe): Solo establece la clave si no existe ya. Esto es útil para operaciones de "solo crear" y patrones de bloqueo simples.SET mi_clave_bloqueo algun_valor_unico NXXX(Existe): Solo establece la clave si ya existe. Esto es útil cuando quieres refrescar una clave conocida sin crear una nueva por error.SET sesion:token:456 nuevo_valor XX
B. Estableciendo Tiempo de Caducidad (TTL)
Para gestionar la memoria e implementar caché basada en tiempo, puedes establecer un tiempo de caducidad directamente dentro del comando SET. Esto es mucho más eficiente que establecer la clave y luego llamar a EXPIRE por separado.
EX segundos: Establece el tiempo de caducidad en segundos.PX milisegundos: Establece el tiempo de caducidad en milisegundos.EXAT timestamp: Establece la caducidad en un timestamp Unix específico (segundos).PXAT timestamp: Establece la caducidad en un timestamp Unix específico (milisegundos).
Ejemplo: establecer una clave para que caduque en una hora:
127.0.0.1:6379> SET cache:producto:500 "Detalles del Producto" EX 3600
OK
127.0.0.1:6379> TTL cache:producto:500
(integer) 3598
Usa SET clave valor EX N o PX N para entradas de caché. Hace que la escritura y la caducidad sean parte de un solo comando, lo que evita el error común donde la aplicación escribe una clave de caché y se bloquea antes de llamar a EXPIRE.
Combinando Opciones
Todas las opciones a menudo se pueden combinar para operaciones atómicas complejas:
# Establece la clave solo si no existe, y haz que caduque en 60 segundos
SET mi_configuracion "activo" NX EX 60
2. Recuperando Datos: El Comando GET
El comando GET recupera el valor de cadena asociado con una clave dada. Es una de las operaciones más rápidas que realiza Redis, a menudo completándose en microsegundos.
Sintaxis y Uso Básico
GET clave
Ejemplo: Recuperando el nombre de usuario almacenado
127.0.0.1:6379> GET usuario:100:nombre
"Alicia García"
Manejo de Claves No Existentes
Si la clave no existe, GET devuelve una respuesta especial indicando que no se encontró nada:
127.0.0.1:6379> GET clave_inexistente
(nil)
En el código de la aplicación, recibir (nil) es la forma estándar de determinar que faltan los datos, generalmente desencadenando un fallo de caché donde la aplicación debe obtener los datos de la fuente primaria (como una base de datos) y posteriormente escribirlos de nuevo en Redis.
Obteniendo un Valor Mientras se Cambia la Caducidad: GETEX
El comando básico GET solo devuelve el valor. No devuelve el TTL restante. Si necesitas el TTL, usa TTL clave o PTTL clave como un comando separado.
GETEX es diferente: devuelve el valor y cambia la caducidad de la clave al mismo tiempo. Eso es útil para el comportamiento de sesión deslizante, donde cada lectura extiende la vida útil de la sesión.
GETEX sesion:abc123 EX 1800
Eso lee el valor de la sesión y restablece la caducidad a 30 minutos. No uses esto casualmente para lecturas de caché normales, porque cada lectura se convierte en una operación similar a una escritura que cambia los metadatos de la clave.
3. Aplicación Práctica: Caché con GET y SET
El caso de uso fundamental para GET y SET es implementar un patrón simple de caché-aside.
Pasos en la lógica de la aplicación:
- Intenta
GET producto:500. - Si Redis devuelve un valor, decodifícalo y devuélvelo.
- Si Redis devuelve nil, obtén el producto de la base de datos primaria.
- Almacena el resultado serializado con
SET producto:500 <json> EX 300. - Devuelve el resultado al llamante.
Este patrón puede reducir la carga de la base de datos, pero también crea una ventana de datos obsoletos. Si el producto cambia en la base de datos, Redis puede seguir sirviendo el valor antiguo hasta que el TTL caduque o tu aplicación invalide la clave. Elige los TTL basándote en cuán incorrectos pueden estar los datos, no solo en cuánto tráfico quieres ahorrar.
Nombrando Claves Sin Crear un Desorden
Redis no requiere una convención de nomenclatura, pero tu yo futuro lo hará. Un patrón legible como usuario:100:nombre, producto:500:resumen, o tasa:usuario:100:inicio_sesion hace que la depuración con redis-cli sea mucho más fácil.
Mantén las claves claras y razonablemente cortas. Ahorrar unos pocos bytes nombrando una clave u:100:n rara vez vale la confusión a menos que estés operando a muy gran escala y hayas medido la sobrecarga de las claves. Para la mayoría de los equipos, la consistencia importa más que la brevedad extrema.
Ten cuidado con los valores proporcionados por el usuario en las claves. Si una dirección de correo electrónico, URL o nombre de inquilino se convierte en parte de la clave, normalízalo primero. De lo contrario, pequeñas diferencias de formato pueden crear entradas de caché duplicadas:
[email protected]
[email protected]
[email protected]
Todos esos pueden representar al mismo usuario para tu aplicación, pero diferentes claves para Redis.
Sobrescrituras, Valores Vacíos y Nil
SET sobrescribe por defecto:
SET config:modo "seguro"
SET config:modo "rápido"
GET config:modo
El valor final es "rápido". Si la sobrescritura fuera peligrosa, usa NX o XX.
También distingue una clave faltante de un valor vacío. Redis nil significa que la clave falta. Una cadena vacía es un valor almacenado real:
SET usuario:100:apodo ""
GET usuario:100:apodo
Tu biblioteca cliente puede representar esos de manera diferente: null, None, nil, una cadena de bytes vacía o una cadena vacía. Verifica el comportamiento del cliente en lugar de adivinar.
Patrón de Bloqueo Seguro, Con una Advertencia
A menudo verás este patrón:
SET bloqueo:factura:123 "trabajador-7:1700000000" NX EX 30
Significa "crea este bloqueo solo si no existe, y hazlo caducar después de 30 segundos." La caducidad no es opcional. Sin ella, un trabajador bloqueado puede dejar un bloqueo para siempre.
Para configuraciones simples de Redis de una sola instancia, este patrón suele ser suficiente para la coordinación de bajo riesgo. Para el bloqueo distribuido crítico a través de fallos, desviación del reloj y múltiples nodos de Redis, usa una biblioteca bien revisada y comprende sus compensaciones. Un error de bloqueo puede convertirse en un error de corrupción de datos.
Depurando con redis-cli
Cuando una ruta de GET o SET se comporta de manera extraña, verifica la clave directamente:
redis-cli GET producto:500
redis-cli TTL producto:500
redis-cli TYPE producto:500
TYPE es útil porque GET solo funciona en valores de cadena. Si la clave contiene un hash, lista, conjunto o conjunto ordenado, Redis devuelve un error de tipo incorrecto. Eso generalmente significa que dos partes de la aplicación están usando el mismo nombre de clave para diferentes propósitos.
Si necesitas inspeccionar varias claves relacionadas durante el desarrollo, SCAN es más seguro que KEYS en un servidor de producción ocupado:
redis-cli SCAN 0 MATCH 'producto:500:*' COUNT 100
KEYS * puede bloquear Redis mientras escanea el espacio de claves. Está bien en una instancia local pequeña. Es un mal hábito en producción.
Eligiendo TTLs en Sistemas Reales
La elección del TTL es una decisión de producto y operaciones, no un truco de Redis. Un caché de perfil de usuario podría tolerar cinco minutos de desactualización. Una verificación de permisos puede necesitar un TTL mucho más corto o una invalidación explícita. Un flag de funcionalidad podría necesitar actualizaciones casi inmediatas si controla un lanzamiento arriesgado.
Aquí hay tres patrones comunes:
SET cache:producto:500 "<json>" EX 300
SET sesion:abc123 "<json>" EX 1800
SET tasa:usuario:100:inicio_sesion "1" EX 60 NX
El caché del producto puede estar un poco desactualizado. La sesión tiene una vida útil clara. La clave de límite de tasa usa NX para que el primer intento cree la ventana y los intentos posteriores puedan incrementar o verificar claves relacionadas dependiendo del diseño.
Evita las claves de "caché para siempre" a menos que tengas una ruta de invalidación clara. Un caché para siempre eventualmente se convierte en una segunda base de datos, generalmente sin la disciplina operativa que aplicas a la base de datos real.
Detalles de Serialización
Las cadenas de Redis son seguras para binarios. Pueden contener JSON, MessagePack, datos comprimidos, contadores o texto plano. El comando no le importa. A tu aplicación sí.
JSON es fácil de inspeccionar:
SET producto:500 "{\"id\":500,\"name\":\"Lámpara de Escritorio\"}" EX 300
Los formatos binarios pueden ahorrar espacio o CPU en algunas aplicaciones, pero dificultan la depuración en terminal. La compresión puede ayudar para datos grandes repetidos, pero también agrega costo de CPU y puede ocultar el hecho de que estás almacenando en caché objetos que son demasiado grandes.
Para contadores, no leas con GET, agregues en la aplicación y escribas con SET si varios clientes pueden actualizar la misma clave. Usa comandos de contador atómico de Redis en su lugar:
INCR pagina:visita:500
EXPIRE pagina:visita:500 86400
Para contadores de primera escritura con caducidad, usa una transacción o un pequeño script Lua si necesitas un comportamiento estricto. De lo contrario, sé claro sobre la condición de carrera que estás aceptando.
Evitando Colisiones de Claves
Dos equipos que usan la misma base de datos Redis pueden reutilizar accidentalmente una clave como usuario:100. Un equipo almacena JSON con SET; otro almacena campos con HSET. El siguiente GET devuelve un error de tipo incorrecto, y ambos equipos pierden tiempo.
Los espacios de nombres ayudan:
tienda:prod:usuario:100:perfil
tienda:prod:sesion:abc123
facturacion:prod:factura:9001
No necesitas claves dolorosamente largas, pero incluye suficiente contexto para evitar colisiones entre entornos, servicios y tipos de datos. Si compartes Redis entre aplicaciones, una convención de nomenclatura es parte de la interfaz.
Cuándo No Usar GET y SET
Las cadenas son el punto de partida, no todo el modelo de Redis. Si actualizas con frecuencia un campo dentro de un blob JSON más grande, un hash puede ser más limpio:
HSET usuario:100 nombre "Alicia García" correo "[email protected]"
HGET usuario:100 correo
Si necesitas eventos ordenados, usa streams o listas. Si necesitas comprobaciones de pertenencia, usa conjuntos. Si necesitas clasificación, usa conjuntos ordenados. Reescribir una cadena serializada completa para cada pequeño cambio es simple al principio, pero puede volverse costoso y engorroso a medida que el objeto crece.
Una Pequeña Lista de Verificación Antes de Publicar
Antes de publicar una nueva ruta de GET y SET, haz algunas preguntas sencillas.
- ¿Cuál es el nombre exacto de la clave?
- ¿Pueden dos servicios usar accidentalmente la misma clave?
- ¿Debería caducar la clave?
- ¿Qué sucede cuando Redis devuelve nil?
- ¿Es aceptable la sobrescritura, o debería la escritura usar
NXoXX? - ¿Es el valor lo suficientemente pequeño para leerlo y escribirlo como una sola cadena?
- ¿Puedes depurar el valor desde
redis-clisi el comportamiento en producción parece incorrecto?
Estas preguntas detectan la mayoría de los errores básicos de cadenas de Redis antes de que se conviertan en incidentes. La sintaxis del comando es fácil. El ciclo de vida alrededor de la clave es donde suelen esconderse los errores.
GET y SET son comandos pequeños con mucho peso operativo. Usa caducidades para datos de caché, usa NX o XX cuando las sobrescrituras importen, trata nil como un estado separado y mantén los nombres de las claves lo suficientemente consistentes como para que alguien pueda depurarlos desde un terminal. Una vez que las cadenas comiencen a sentirse apretadas, mueve los campos relacionados a hashes y usa la estructura de datos que coincida con el patrón de acceso.