Caché en Kotlin: Redis y otras soluciones
El caché es uno de los mecanismos clave para optimizar el rendimiento en aplicaciones modernas. En el ecosistema de Kotlin, gracias a la compatibilidad total con Java y la rica base de bibliotecas de JVM, están disponibles todas las herramientas principales para trabajar con caché. En este artículo, veremos cómo organizar el caché en Kotlin usando Redis, Caffeine y Ehcache, y analizaremos cuándo elegir cada herramienta.
¿Por qué es necesario el caché?
El caché permite reducir el tiempo de respuesta de la aplicación almacenando datos solicitados con frecuencia en memoria de acceso rápido. Esto es especialmente relevante para:
- API REST de alta carga;
- trabajo con API externas y bases de datos;
- cálculos que consumen muchos recursos;
- datos de sesión de usuarios.
Estrategias principales de caché
Antes de elegir una biblioteca, es importante comprender las estrategias básicas:
- Cache-Aside — la aplicación gestiona el caché por sí misma: primero verifica el caché, en caso de fallo carga los datos de la BD y los coloca en el caché.
- Read-Through — el caché carga automáticamente los datos desde la fuente en caso de fallo.
- Write-Through / Write-Behind — la escritura de datos se realiza simultáneamente (o de forma asíncrona) en el caché y en el almacenamiento principal.
1. Redis desde Kotlin
Redis es un almacenamiento key-value en memoria que se utiliza a menudo como caché distribuido. Para trabajar con Redis en Kotlin se utiliza el cliente Lettuce (asíncrono, reactivo) o Jedis (síncrono).
Conexión con Lettuce
// build.gradle.ktsimplementation("io.lettuce:lettuce-core:6.3.2.RELEASE")Ejemplo de trabajo con Redis mediante Lettuce (Kotlin)
import io.lettuce.core.RedisClientimport io.lettuce.core.api.coroutines
suspend fun main() { val client = RedisClient.create("redis://localhost:6379") val connection = client.connect() val commands = connection.coroutines() // API de corrutinas
// Escritura commands.setex("user:123:profile", 3600, "{\\"name\\":\\"Alice\\"}") // Lectura val cached = commands.get("user:123:profile") println("Desde caché: $cached") connection.close() client.shutdown()}¿Cuándo usar Redis?
- Se necesita un caché distribuido entre varias instancias de la aplicación.
- Se requiere alta tolerancia a fallos y replicación.
- Los datos deben estar disponibles después de reiniciar la aplicación (persistencia de Redis).
- Se necesita soporte para estructuras complejas (listas, conjuntos, colas).
2. Caffeine — caché local de alto rendimiento
Caffeine es una biblioteca para caché en memoria en JVM, escrita en Java. Se usa a menudo junto con Spring Boot, pero también funciona muy bien en Kotlin puro. Caffeine proporciona una latencia casi nula en las lecturas.
Conexión con Caffeine
// build.gradle.ktsimplementation("com.github.ben-manes.caffeine:caffeine:3.1.8")Ejemplo de uso de Caffeine en Kotlin
import com.github.benmanes.caffeine.cache.Caffeineimport java.util.concurrent.TimeUnit
data class User(val id: Int, val name: String)
fun createCache(): Caffeine<Int, User>.() -> Unit = { maximumSize(10_000) expireAfterWrite(10, TimeUnit.MINUTES) recordStats()}
val userCache = Caffeine.newBuilder() .maximumSize(10_000) .expireAfterWrite(10, TimeUnit.MINUTES) .build<Int, User>()
fun getUserFromCache(id: Int): User? { return userCache.getIfPresent(id)}
fun putUser(id: Int, user: User) { userCache.put(id, user)}
// Ejemplo con carga automática (LoadingCache)val loadingCache = Caffeine.newBuilder() .maximumSize(5_000) .build<Int, User> También en la biblioteca
GraphQL en C# (.NET): bibliotecas Hot Chocolate y GraphQL.NET para crear API
ASIO para C++: guía completa con ejemplos
Geolocalización y mapas en PHP: revisión de bibliotecas y herramientas
Eloquent ORM para PHP: guía completa con ejemplos
Trabajo con fechas en Kotlin: bibliotecas y herramientas (Kotlinx-datetime, Joda-Time, java.time)