Curso exprés · No. 15
Una cache es un lugar pequeño y rápido donde guardas una respuesta que ya resolviste, para que la próxima vez que la necesites la leas en lugar de rehacer el trabajo. Es el mayor truco de velocidad de la informática — y viene con el problema difícil más famoso de la informática: saber cuándo la respuesta recordada se ha quedado obsoleta.
Solo lo esencial · Una imagen por idea · Aprende las palabras
Una cache es una idea sencilla: guarda una copia de una respuesta en algún lugar rápido, para no pagar por producirla dos veces. Entiende esto y toda cache que conozcas será el mismo truco en un lugar distinto.
Una cache recuerda la respuesta
Un cuaderno de notas en tu escritorio junto a un archivador lento — una vez que has buscado algo, lo apuntas, y la próxima vez lees la nota en lugar de cruzar la sala otra vez.
Una cache es un almacén pequeño y rápido que guarda el resultado de un trabajo costoso — una consulta a la base de datos, una página calculada, un archivo descargado — para que la siguiente petición sea barata. Lo costoso ocurre una vez; la lectura barata ocurre muchas veces. Ese es todo el principio. Lo demás son detalles sobre dónde vive el cuaderno y cuándo confiar en lo que hay escrito en él.
Acierto y fallo son los dos resultados
Buscas la nota. O está ahí y la lees al instante — o está en blanco, y al final tienes que caminar hasta el archivador.
Cuando la respuesta está en la cache, eso es un cache hit — rápido y barato. Cuando no lo está, eso es un cache miss — haces el trabajo lento y, normalmente, guardas el resultado para que la próxima vez sea un acierto. Estas dos palabras describen toda interacción con una cache. Todo el juego del caching consiste en convertir fallos en aciertos: asegurarte de que la respuesta esté ahí cuando la busques.
Funciona gracias a la repetición
Una cafetería que se memoriza los pedidos de sus clientes habituales — solo vale la pena porque las mismas personas piden lo mismo una y otra vez.
El caching rinde cuando las mismas respuestas se necesitan repetidamente — y casi todo en la informática es repetitivo. La misma página popular, el perfil del mismo usuario, la misma búsqueda, pedidos miles de veces. Como el acceso no es aleatorio sino que se concentra en unos pocos elementos calientes, una cache pequeña con los más populares puede absorber una porción enorme del trabajo. Sin repetición, no hay razón para cachear.
Una cache guarda una copia rápida de una respuesta costosa. Un acierto es leer la nota; un fallo es la caminata hasta el archivador. El trabajo es convertir fallos en aciertos.
El caching no es una sola cosa en un solo lugar — es un patrón que se repite en cada capa entre un usuario y los datos. Cuanto más cerca está la copia de quien la necesita, más rápida es.
Cuanto más cerca la cache, más rápido el acierto
Provisiones que guardas en tu escritorio, en la sala, en el edificio y en un almacén al otro lado de la ciudad — cuanto más cerca está, más rápido lo obtienes, pero menos puedes almacenar.
Hay una escalera de caches entre un usuario y la verdad, cada una más cercana y rápida que la anterior: el navegador guarda archivos en tu dispositivo, una CDN guarda copias cerca de tu ciudad, la aplicación mantiene datos calientes en memoria, y la CPU tiene caches diminutas a nanosegundos de distancia. Las caches más cercanas son más rápidas pero más pequeñas. Una petición prueba primero la más cercana y va saliendo hacia afuera en cada fallo.
Los almacenes en memoria como Redis son el caballo de batalla
Un empleado que mantiene los archivos más pedidos sobre el escritorio, a un brazo de distancia, en vez de ir a buscar cada uno al archivo del sótano cada vez.
La mayoría de las apps colocan una cache en memoria dedicada — una herramienta como Redis o Memcached — entre la aplicación y la base de datos. La memoria es muchísimo más rápida que el disco, así que mantener ahí los resultados calientes convierte una consulta lenta a la base de datos en una lectura casi instantánea. Cuando la gente dice «añade una cache» para acelerar un backend, normalmente se refiere a esto: un almacén rápido en memoria delante de una fuente de verdad lenta.
La CDN cachea la web cerca del usuario
Libros populares en existencia en bibliotecas locales por todas partes, para que nadie tenga que pedir por correo a un único archivo central.
Una CDN (red de distribución de contenidos) es caching aplicado a la geografía: guarda copias de tus páginas, imágenes y archivos en servidores por todo el mundo, sirviendo a cada usuario desde uno cercano. Por eso un sitio global carga rápido en todas partes y no solo cerca de su servidor de origen. Es la misma idea de acierto/fallo que en cualquier otro sitio — la copia simplemente está repartida por el mapa para vencer a la distancia.
El caching es un patrón que se repite en cada capa: navegador, CDN, almacén en memoria, CPU. Más cerca es más rápido pero más pequeño — y un fallo cae hacia afuera, a la siguiente.
Una cache solo vale su complejidad si de verdad está atrapando la mayoría de las peticiones. Un solo número — el hit ratio — te dice si tu cache se está ganando el sueldo.
El hit ratio es el marcador que cuenta
A un portero se le juzga por la proporción de tiros que para. Uno que ataja el 95% es transformador; uno que ataja el 10% apenas cambia el partido.
El hit ratio es la fracción de peticiones servidas desde la cache en vez de desde la fuente lenta. Un hit ratio del 95% significa que solo una petición de cada veinte llega a la base de datos — una reducción enorme de carga y latencia. Un hit ratio del 10% significa que la cache es sobre todo coste extra. Este único número es como juzgas si una cache está funcionando, y mejorarlo es la palanca principal que ajustas.
Una cache cold tiene que calentarse
Una tienda nueva con estanterías vacías no sirve a nadie rápido al principio — se va surtiendo a medida que los clientes piden, hasta que los artículos populares están siempre a mano.
Justo después de arrancar, una cache está cold — vacía, así que toda petición falla y va a la fuente lenta. A medida que fluye el tráfico real, se llena de respuestas populares y se vuelve warm, y el hit ratio sube. Por eso el rendimiento puede verse mal justo tras un reinicio o un despliegue, y luego estabilizarse. Algunos sistemas hacen pre-warm de la cache a propósito, cargando datos calientes conocidos antes de que lleguen los usuarios.
Una cache cambia memoria por velocidad
Alquilar un escritorio más grande para que quepan más archivos al alcance del brazo — cuesta más espacio, pero caminas hasta el archivador mucho menos.
El caching no es gratis: gastas memoria (que es limitada y cuesta dinero) para ahorrar tiempo. Una cache más grande guarda más y acierta más a menudo, pero no puedes cachearlo todo — así que el arte está en cachear las cosas correctas: las respuestas calientes, costosas y pedidas repetidamente que dan más velocidad por byte almacenado. Una cache es un intercambio deliberado, y el hit ratio te dice si el intercambio está rindiendo.
El hit ratio es el boletín de notas de la cache. Gastas memoria para comprar velocidad — así que cachea las respuestas calientes y costosas que ganan más aciertos por byte.
Una respuesta recordada puede quedarse desactualizada mientras sigues confiando en ella. Saber cuándo dejar de confiar en la copia es el problema central, y genuinamente difícil, del caching.
Los datos obsoletos son el precio del caching
Ese número de teléfono que apuntaste en una nota adhesiva es oro — hasta que tu amigo se muda y la nota se vuelve, en silencio, incorrecta.
La otra cara de recordar una respuesta es que la respuesta real puede cambiar mientras tu copia no. Los datos stale son un valor cacheado que ya no coincide con la verdad — el precio antiguo, la publicación borrada, el recuento de existencias de la última hora. Toda cache corre el riesgo de servir datos stale, y decidir cuánta obsolescencia puedes tolerar es la primera pregunta de diseño real de cualquier cache.
TTL: deja que expire con un temporizador
Leche marcada con una fecha de caducidad — pasada esa fecha, no confías en ella sin comprobar, aunque siga teniendo buen aspecto.
La herramienta de frescura más sencilla es un TTL (time to live): cada entrada cacheada recibe una expiración, y pasada esa expiración la entrada se trata como inexistente, forzando una nueva lectura. Un TTL corto significa datos más frescos pero más fallos; un TTL largo significa más aciertos pero más obsolescencia. Elegir el TTL es elegir tu punto exacto en el intercambio entre frescura y velocidad — por cada tipo de dato, según con qué rapidez cambia de verdad.
Por qué esto es célebremente difícil
Saber el instante exacto en que un hecho cambió en algún otro lugar del mundo, para romper tu nota en el momento justo — fácil de decir, enloquecedor de hacer.
Hay un chiste recurrente que dice que solo hay dos problemas difíciles en la informática, y la cache invalidation — saber cuándo hay que descartar un valor cacheado — es uno de ellos. Es difícil porque a menudo la cache no sabe que los datos subyacentes cambiaron; el cambio ocurrió en otra parte. La siguiente sección es el conjunto de estrategias que la gente usa para combatir exactamente este problema.
Toda respuesta cacheada puede quedar stale. Un TTL la expira con un temporizador — y saber exactamente cuándo invalidar es uno de los problemas genuinamente difíciles de la informática.
Dos fuerzas deciden qué hay en una cache y si es de fiar: cómo la actualizas cuando la verdad cambia, y cómo haces sitio cuando está llena. Ambas tienen estrategias con nombre que vale la pena conocer.
Cache-aside: la app llena la cache
Consultas primero tu cuaderno; si está en blanco, caminas hasta el archivador, lees el archivo y apuntas la respuesta antes de seguir.
El patrón más común es cache-aside (carga perezosa): en una lectura, la app consulta la cache; en un fallo, busca en la fuente, guarda el resultado y lo devuelve. La cache se llena bajo demanda con exactamente lo que se pide de verdad. Es simple y popular — y su punto débil es la obsolescencia, ya que un valor permanece en la cache hasta que algo expira o lo invalida.
Write-through y write-around: mantener las escrituras consistentes
Cuando un hecho cambia, puedes actualizar la nota del escritorio en el mismo momento en que actualizas el archivo maestro — o saltarte la nota y dejar que se vuelva a leer fresca la próxima vez.
Cuando los datos se escriben, eliges cómo se mantiene al día la cache. Write-through actualiza la cache y la fuente a la vez, de modo que la cache nunca queda stale (a costa de escrituras más lentas). Write-around escribe solo en la fuente y deja que la cache falle y recargue más tarde, evitando cachear datos que nadie vuelve a leer. Estos nombres describen dónde aterriza una escritura y cuándo se entera la cache — y cuál eliges depende de tu mezcla de lecturas y escrituras.
Desalojo: decidir qué soltar cuando está llena
Un escritorio pequeño que está lleno — para añadir un archivo nuevo debes guardar uno, así que retiras el que no has tocado desde hace siglos, no el que usas cada hora.
Una cache tiene espacio limitado, así que cuando se llena debe desalojar algo. La política más común es LRU (least recently used): suelta lo que no se ha tocado en más tiempo, apostando a que no se necesitará pronto. Existen otras — LFU suelta lo menos usado por frecuencia. El desalojo es como una cache pequeña conserva automáticamente los elementos calientes y se deshace de los fríos, manteniendo su hit ratio alto sin crecer para siempre.
La invalidación decide cuándo un valor cacheado es incorrecto; el desalojo decide qué soltar cuando se acaba el espacio. Cache-aside, write-through, LRU — nombres para esos dos trabajos.
El poder del caching viene con bordes afilados. Los fallos clásicos no son exóticos — son predecibles, tienen nombre, y conocerlos es la mitad de evitarlos.
El stampede cuando expira una clave caliente
Un artículo popular se agota, y en el instante en que lo hace, cien clientes se abalanzan a la vez sobre el mostrador a pedirlo — desbordando al único empleado que repone existencias.
Cuando una entrada cacheada popular expira, toda petición que la quería falla en el mismo momento y todas golpean la fuente lenta a la vez — un cache stampede (o thundering herd). La base de datos, protegida durante horas, recibe de repente a toda la multitud de golpe y puede ceder. Los arreglos se conocen — deja que una petición refresque mientras las demás esperan, o escalona las expiraciones — pero tienes que anticiparlo; un stampede aparece justo cuando el tráfico está más alto.
Lecturas stale: rápidas, seguras de sí mismas y equivocadas
Leer un precio de una nota adhesiva vieja y citarlo con confianza — el número se entrega al instante, y es el número equivocado.
Una cache servirá encantada un valor stale rápido y con plena confianza. Normalmente eso está bien — un recuento de vistas un poco viejo no le hace daño a nadie. Pero para datos donde la corrección es crítica — un saldo bancario, el inventario, los permisos — una lectura stale puede ser un error de verdad. La habilidad está en saber qué datos toleran obsolescencia y cuáles deben estar siempre frescos, y nunca cachear los segundos a la ligera.
Algunas cosas no deberían cachearse en absoluto
No guardas una fotocopia de un documento que se reescribe cada minuto, ni de la carta privada de alguien sobre un escritorio compartido — la copia es incorrecta, o no debería estar ahí.
No todo pertenece a una cache. Los datos que cambian constantemente dan un hit ratio pobre y obsolescencia frecuente. Los datos sensibles o por usuario corren el riesgo de filtrarse si una cache compartida entrega la copia de un usuario a otro. Y los datos que rara vez se piden simplemente malgastan espacio. Saber qué no cachear — datos que cambian rápido, sensibles o impopulares — es tan importante como saber qué cachear.
Los mordiscos clásicos del caching tienen nombre: stampedes cuando expira una clave caliente, lecturas stale servidas con falsa confianza, y cachear cosas que nunca deberían estarlo.
El caching es una herramienta poderosa: enorme velocidad por un poco de memoria, pagada con el riesgo de servir el pasado. Usado con intención, es uno de los mejores intercambios de la informática.
Cachea lo caliente, lo costoso y lo que cambia lento
Te memorizas los pedidos habituales de los clientes y las indicaciones que das diez veces al día — no las peticiones puntuales ni las cosas que cambian cada minuto.
El objetivo ideal de una cache es algo leído con frecuencia, costoso de producir y rara vez cambiado — esa combinación rinde la mayor velocidad con el menor riesgo de obsolescencia. Una página popular construida a partir de una consulta lenta, recalculada igual todo el día, es perfecta. Un valor que cambia constantemente, rara vez leído y sensible es lo contrario. La mayoría de las victorias del caching vienen de encontrar el puñado de respuestas que encajan en la primera descripción y recordar exactamente esas.
Decide de antemano tu presupuesto de obsolescencia
Acordar por adelantado cuán desactualizado es aceptable — un widget del tiempo puede tener minutos de antigüedad; un saldo bancario no puede tener segundos.
Antes de cachear nada, decide cuánta obsolescencia puede tolerar, porque esa elección manda sobre todo lo demás — el TTL, si necesitas invalidación activa, si es seguro cachearlo siquiera. Hazlo explícito por cada tipo de dato. «¿Cuán equivocado se le permite estar, y durante cuánto tiempo?» es la pregunta que convierte el caching de una fuente de errores misteriosos en un intercambio controlado y deliberado.
- ¿Está caliente el dato — se pide con la frecuencia suficiente para dar un hit ratio real? - ¿Es costoso de producir, de modo que un acierto ahorre trabajo significativo? - ¿Cuán obsoleto puede estar — cuál es el TTL, y necesito invalidación activa? - ¿Qué pasa cuando expira una entrada caliente — podría causar un stampede? - ¿Es seguro cachearlo — no datos secretos por usuario en una cache compartida? - ¿Cómo sabré que funciona — estoy midiendo el hit ratio?
- cache hit / miss — respuesta encontrada en la cache, o no. - hit ratio — la porción de peticiones servidas desde la cache; el marcador que cuenta. - cold / warm cache — vacía y fallando, frente a llena y acertando. - TTL / stale — el temporizador de expiración, y una copia que ya no coincide con la verdad. - invalidación / desalojo — descartar datos incorrectos, y soltar datos para hacer sitio (LRU). - cache-aside / write-through — la app la llena perezosamente, o las escrituras la actualizan de inmediato. - stampede / thundering herd — la avalancha hacia la fuente cuando expira una clave caliente.
- Sabes nombrar el hit ratio de tus caches importantes. - Cada cosa cacheada tiene un TTL deliberado ajustado a con qué rapidez cambia de verdad. - Nada por usuario ni secreto está en una cache compartida por accidente. - Tus claves calientes no harán stampede a la fuente todas a la vez al expirar. - Cacheas las respuestas calientes, costosas y de cambio lento — y dejas fuera el resto.
El caching cambia un poco de memoria por enorme velocidad, a riesgo de servir el pasado. Bien hecho, es deliberado: las respuestas correctas, con un presupuesto de obsolescencia que elegiste a propósito.