Introducción
Una pequeña tienda guarda los precios de referencia en una base de datos primaria preparada y usa Redis para recordar los precios que los clientes ya han consultado. Las consultas repetidas deben usar ese valor recordado. Sin embargo, un mismo SKU puede tener precios diferentes en distintas tiendas o monedas, y un precio recordado debe caducar en algún momento.
Entregarás un breve policy.py que elija la identidad completa de caché y dé a cada carga una duración finita. Necesitas conocimientos básicos para moverte por la terminal y de GET/SET en Redis. Aquí se explican la plantilla Python y cada expresión que cambias; no se requiere un curso previo de Python. La fuente primaria es una base de datos SQLite preparada, no una segunda tarea de implementación de base de datos. Esta unidad independiente usa solo Terminal, con sus propios datos nuevos.
Edita únicamente /home/labex/project/cache-desk/policy.py. Conserva las herramientas proporcionadas, la tabla fuente, todas las identidades y precios fuente y la nota de catálogo ajena a la tarea. Usa solo la API documentada de fuente y caché y expresiones ordinarias de política en las tres funciones; deja fuera de la política las importaciones, la ejecución de comandos y los recursos ajenos. No desactives la caché, vacíes Redis de forma general ni cambies la configuración global. Probamos solicitudes secuenciales controladas, sin garantía de latencia de producción ni de consistencia fuerte. El tiempo estimado por el autor incluye lectura y errores habituales; no se ha cronometrado con principiantes.
Separar los precios que realmente solicitan los clientes
En este paso, observarás un acierto real de caché, encontrarás una colisión de claves e incluirás la identidad completa de cada precio en su clave.
Empieza en Terminal, en el indicador del intérprete del sistema. cd cambia el directorio actual; esta ruta absoluta funciona desde cualquier directorio. ./desk ejecuta un programa preparado de ese directorio. Cada comando siguiente es un comando independiente del intérprete del sistema, no una entrada para un indicador interactivo de Redis.
cd /home/labex/project/cache-desk
./desk status
Lee el orden de columnas: shop / sku / currency / integer cents. North MUG USD cuesta 1200 centavos, South MUG USD cuesta 1500, North MUG EUR cuesta 1100 y North FREE USD cuesta 0. La presentación de estado lee los precios de referencia; nunca carga la caché.
Un fallo de caché significa que Redis no tiene ningún valor para la clave solicitada. Un acierto de caché significa que sí lo tiene. Esta aplicación preparada usa cache-aside: lee primero Redis, lee la fuente primaria solo cuando no hay valor y después recuerda el resultado. Prueba dos veces la misma solicitud normal:
./desk view north MUG USD
./desk view north MUG USD
El primer resultado debería mostrar "cents": 1200, "origin": "source", "primary_selects": 1; el segundo muestra "origin": "cache", "primary_selects": 0. El recuento procede de trazas nativas de SELECT de SQLite para esta solicitud, no de una mejora de velocidad estimada. La salida JSON usa nombres de campo entre comillas; estos tres campos identifican el precio, el origen y las lecturas de la fuente primaria.
Ahora solicita otra tienda e inspecciona la clave real de Redis:
./desk view south MUG USD
./desk inspect south MUG USD
./desk policy
La clave incompleta usa solo MUG. Puede devolver los 1200 de North para South, aunque la fuente primaria siga almacenando 1500. inspect lee la clave y su valor real; no repara el precio. El prefijo proporcionado catalog delimita las claves de este curso. Cada clave debe empezar con el prefijo proporcionado seguido de dos puntos, como catalog:. El sufijo debe distinguir los tres campos de identidad, no solo el SKU; se aceptan codificaciones equivalentes del sufijo.
La plantilla es Python. def define una función; los nombres entre paréntesis son sus argumentos. Un cuerpo con sangría pertenece a esa función. return proporciona su resultado. identity es una tupla de tres elementos, en el orden de campos mostrado: identity[0] es la tienda, [1] el SKU y [2] la moneda. Los índices empiezan en cero. f"...{name}..." inserta una expresión en una cadena; aquí los dos puntos son separadores ordinarios. Los identificadores del curso contienen solo letras, dígitos, guiones y guiones bajos, por lo que no pueden contener ese separador. Este formato de clave no es una codificación general para texto arbitrario de usuario.
En read_price, = asigna un valor. cache.command("GET", key) envía un comando real a Redis. None significa que no hay valor en caché; if value is not None: entra en la rama solo cuando existe un valor. Esta comprobación explícita conserva un precio cero. Redis devuelve su valor como cadena, por lo que int(value) lo convierte en centavos enteros. La coma de return cents, "source" devuelve un par. source.read(identity) ejecuta el SELECT preparado de la fuente primaria y lanza un error de búsqueda para una identidad desconocida. No hay un precio de referencia alternativo.
Guarda un archivo completo con una clave completa. cat > policy.py reemplaza ese archivo; el marcador de here-document entre comillas 'POLICY' hace que el intérprete copie literalmente cada línea siguiente hasta la línea independiente POLICY. Copia el bloque entero manteniendo cuatro espacios de sangría. Las funciones repetidas conservan el comportamiento de lectura preparado; en este paso solo cambia la decisión de clave.
cat > policy.py <<'POLICY'
def cache_key(prefix, identity):
return f"{prefix}:{identity[0]}:{identity[1]}:{identity[2]}"
def read_price(source, cache, prefix, identity):
key = cache_key(prefix, identity)
value = cache.command("GET", key)
if value is not None:
return int(value), "cache"
cents = source.read(identity)
cache.command("SET", key, cents)
return cents, "source"
def change_price(source, cache, prefix, identity, cents):
source.write(identity, cents)
POLICY
Consulta cada identidad dos veces:
./desk view north MUG USD
./desk view north MUG USD
./desk view south MUG USD
./desk view south MUG USD
./desk view north MUG EUR
./desk view north MUG EUR
./desk view north FREE USD
./desk view north FREE USD
La primera lectura de cada clave completa nueva procede de la fuente y la segunda de Redis. Los precios son 1200, 1500, 1100 y 0 respectivamente. Un acierto de caché con un precio incorrecto no es un éxito. La antigua clave desechable catalog:MUG ya no se usa; no hace falta ningún borrado general.
Si escribes ./deskk, el intérprete informa de que falta el archivo. ls enumera las herramientas reales; vuelve a ejecutar ./desk con el nombre correcto. Si Python informa de un error de sintaxis o sangría, muestra ./desk policy y vuelve a copiar el bloque completo del archivo conservando los espacios iniciales. No reinicies la VM ni cambies las herramientas preparadas. La comprobación de este paso ejercita identidades diferentes en un entorno de prueba desechable y conserva la fuente primaria real; no exige una forma concreta de escribir la clave.
Dar a cada carga una fecha límite
En este paso, añadirás una duración finita cuando un precio entre en Redis e impedirás que los aciertos de caché desplacen esa fecha límite.
Continúa en Terminal, en /home/labex/project/cache-desk. Inspecciona una clave completa existente:
./desk inspect north MUG USD
pttl_ms es la duración restante en milisegundos. -1 significa que la clave no tiene caducidad; -2 significa que no existe. Un valor positivo disminuye con el tiempo. Un valor sin fecha límite puede sobrevivir indefinidamente a un cambio externo de precio.
SET key value EX seconds de Redis almacena el valor y su caducidad en un único comando. Elige 15 segundos para esta tienda de enseñanza; cada nueva carga aceptada debe tener un TTL inicial de entre 12 y 20 segundos. Este intervalo corto permite observar la caducidad natural; no es una recomendación de TTL para producción. Establece la fecha límite solo cuando falte el valor. Renovarla en cada acierto puede mantener vivo indefinidamente un precio obsoleto popular. Un SET sin opciones que sobrescribe una clave con caducidad elimina la caducidad anterior salvo que se haya solicitado explícitamente conservarla.
Reemplaza el archivo por la misma identidad completa y un SET con duración. En Python, los argumentos separados "EX", 15 se pasan a Redis; 15 es un entero, no un identificador entre comillas.
cat > policy.py <<'POLICY'
def cache_key(prefix, identity):
return f"{prefix}:{identity[0]}:{identity[1]}:{identity[2]}"
def read_price(source, cache, prefix, identity):
key = cache_key(prefix, identity)
value = cache.command("GET", key)
if value is not None:
return int(value), "cache"
cents = source.read(identity)
cache.command("SET", key, cents, "EX", 15)
return cents, "source"
def change_price(source, cache, prefix, identity, cents):
source.write(identity, cents)
POLICY
Los valores con identidad completa cargados en el paso anterior siguen sin caducidad: cambiar el código no les añade una fecha límite retroactivamente. forget borra deliberadamente solo la clave actual de caché de una identidad conocida, sin tocar su precio primario ni otras claves. Elimina individualmente estas cuatro entradas de práctica explícitamente desechables. Es una acción explícita del estudiante, nunca un vaciado general ni una reparación oculta del lector. Todas las cargas posteriores usarán la nueva fecha límite. Después carga el precio de North e inspecciónalo:
./desk forget north MUG USD
./desk forget south MUG USD
./desk forget north MUG EUR
./desk forget north FREE USD
./desk view north MUG USD
./desk inspect north MUG USD
./desk view north MUG USD
./desk inspect north MUG USD
La primera consulta es source/1 y la siguiente cache/0 si se emite antes de caducar. El PTTL positivo disminuye en lugar de volver a 15000. Si la lectura lleva más de 15 segundos, se espera un fallo real de caché: repite enseguida los comandos de carga e inspección, sin cambiar tu política.
También puedes leer valores nativos de Redis mediante la conexión proporcionada de solo lectura. ./redis envía sus argumentos al Redis privado de este curso, no al servicio Redis genérico:
./redis GET catalog:north:MUG:USD
./redis TTL catalog:north:MUG:USD
El envoltorio imprime una cadena JSON como "1200", un TTL entero nativo o null para un valor ausente. Nunca obtiene un precio ausente. Ahora sleep 16 pide al intérprete esperar 16 segundos reales. No simula el tiempo ni borra una clave por ti:
sleep 16
./desk inspect north MUG USD
./desk view north MUG USD
./desk view north MUG USD
Antes de volver a cargar, inspect muestra value: null y PTTL -2. La siguiente consulta lee de nuevo la fuente y la posterior puede acertar en Redis. Todos los precios de referencia permanecen sin cambios en esta unidad. El evaluador prueba la caducidad real en claves aisladas; las claves reales pueden caducar naturalmente mientras lees, por lo que completar la tarea no depende de competir contra una cuenta atrás corta.
Resumen
Separaste tienda, SKU y moneda en claves reales de Redis, conservaste precios cero, verificaste aciertos de caché frente a lecturas de la fuente primaria y diste a cada carga una duración que no se renueva con los accesos. Tu política es reutilizable; la fuente primaria preparada y los datos de catálogo ajenos a la tarea permanecen intactos.



