Caching en Java: Redis, Memcached y soluciones integradas

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué es necesario el almacenamiento en caché en Java?



Las aplicaciones Java modernas a menudo trabajan con grandes volúmenes de datos. Cada solicitud a la base de datos o a una API externa implica costos de tiempo y recursos. Sin almacenamiento en caché, al aumentar la carga, el rendimiento disminuye y el tiempo de respuesta aumenta. El almacenamiento en caché permite almacenar datos solicitados con frecuencia en acceso rápido (en la memoria RAM), lo que reduce las latencias y disminuye la carga en el backend.



En Java, existen tres enfoques principales para el almacenamiento en caché: soluciones integradas (por ejemplo, HashMap o Caffeine), sistemas distribuidos (Redis y Memcached). En este artículo, analizaremos cada uno de ellos, proporcionaremos ejemplos de código y ayudaremos a elegir la opción óptima para su proyecto.



1. Almacenamiento en caché integrado en Java



El almacenamiento en caché integrado es la forma más sencilla de acelerar una aplicación. Los datos se almacenan directamente en la memoria de la JVM. Las principales ventajas: latencia de acceso mínima, facilidad de configuración. Desventajas: capacidad limitada (depende del heap), los datos se pierden al reiniciar la aplicación.



1.1. Almacenamiento en caché simple mediante HashMap



La opción más básica es usar ConcurrentHashMap con gestión manual del tiempo de vida. Es adecuado para prototipos, pero no para producción (sin limpieza automática, posibles fugas de memoria).



import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.TimeUnit;

public class SimpleCache { private final ConcurrentHashMap<String, CacheEntry> cache = new ConcurrentHashMap<>();

public void put(String key, Object value, long ttlMillis) { cache.put(key, new CacheEntry(value, System.currentTimeMillis() + ttlMillis)); }

public Object get(String key) { CacheEntry entry = cache.get(key); if (entry == null || System.currentTimeMillis() > entry.expiry) { cache.remove(key); return null; } return entry.value; }

private static class CacheEntry { private final Object value; private final long expiry; // constructor y getters }}


1.2. Caffeine — biblioteca moderna de almacenamiento en caché



Caffeine es una biblioteca de alto rendimiento para Java que se utiliza por defecto en Spring Cache. Admite expulsión automática por tiempo, tamaño, así como elementos ponderados. Caffeine funciona más rápido que Guava Cache (en la que se basa).



import com.github.benmanes.caffeine.cache.Cache;import com.github.benmanes.caffeine.cache.Caffeine;import java.util.concurrent.TimeUnit;

public class CaffeineExample { public static void main(String[] args) { Cache<String, String> cache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(1000) .build();

cache.put("user:123", "John Doe"); String user = cache.getIfPresent("user:123"); System.out.println("Cached user: " + user); }}


Para producción, se recomienda usar Caffeine o Ehcache (que admite almacenamiento en disco). Las soluciones integradas son ideales para microservicios y monolitos con una sola instancia.



2. Memcached: almacenamiento en caché distribuido para Java



Memcached es un sistema de almacenamiento en caché distribuido que funciona en memoria RAM. Es simple, rápido y admite escalado horizontal. Características principales:

  • Almacenamiento en forma de pares "clave-valor" (tamaño máximo del valor: 1 MB).
  • No admite persistencia (los datos se pierden al reiniciar).
  • No tiene autenticación ni cifrado integrados.

Para trabajar con Memcached en Java, se utiliza con mayor frecuencia la biblioteca SpyMemcached o

Blogs

Book Recommendations