Cache em Kotlin: Redis e outras soluções
Cache é um dos mecanismos-chave para otimização de desempenho em aplicações modernas. No ecossistema Kotlin, graças à total compatibilidade com Java e à rica base de bibliotecas JVM, todas as principais ferramentas para trabalhar com cache estão disponíveis. Neste artigo, veremos como organizar o cache em Kotlin usando Redis, Caffeine e Ehcache, e também analisaremos quando escolher cada ferramenta.
Por que precisamos de cache?
O cache permite reduzir o tempo de resposta da aplicação armazenando dados frequentemente solicitados em memória de acesso rápido. Isso é especialmente relevante para:
- APIs REST de alta carga;
- trabalho com APIs externas e bancos de dados;
- cálculos que consomem muitos recursos;
- dados de sessão de usuários.
Principais estratégias de cache
Antes de escolher uma biblioteca, é importante entender as estratégias básicas:
- Cache-Aside — a aplicação gerencia o cache por conta própria: primeiro verifica o cache, em caso de falta carrega os dados do banco e os coloca no cache.
- Read-Through — o cache carrega automaticamente os dados da fonte em caso de falta.
- Write-Through / Write-Behind — gravação de dados simultaneamente (ou assincronamente) no cache e no armazenamento principal.
1. Redis a partir do Kotlin
Redis é um armazenamento in-memory key-value, frequentemente usado como cache distribuído. Para trabalhar com Redis em Kotlin, utiliza-se o cliente Lettuce (assíncrono, reativo) ou Jedis (síncrono).
Conexão com Lettuce
// build.gradle.ktsimplementation("io.lettuce:lettuce-core:6.3.2.RELEASE")Exemplo de trabalho com Redis via 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 corrotinas
// Escrita commands.setex("user:123:profile", 3600, "{\\"name\\":\\"Alice\\"}") // Leitura val cached = commands.get("user:123:profile") println("Do cache: $cached") connection.close() client.shutdown()}Quando usar Redis?
- Necessidade de cache distribuído entre várias instâncias da aplicação.
- Requer alta tolerância a falhas e replicação.
- Dados devem estar disponíveis após reinicialização da aplicação (persistência do Redis).
- Necessidade de suporte a estruturas complexas (listas, conjuntos, filas).
2. Caffeine — cache local de alto desempenho
Caffeine é uma biblioteca para cache in-memory na JVM, escrita em Java. É frequentemente usada em conjunto com Spring Boot, mas funciona perfeitamente também em Kotlin puro. Caffeine oferece latência quase zero na leitura.
Conexão com Caffeine
// build.gradle.ktsimplementation("com.github.ben-manes.caffeine:caffeine:3.1.8")Exemplo de uso do Caffeine em 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)}
// Exemplo com carregamento automático (LoadingCache)val loadingCache = Caffeine.newBuilder() .maximumSize(5_000) .build<Int, User> Também na biblioteca
Trabalho com arquivos ZIP em Go (Golang): criação, leitura e extração de arquivos
Frameworks CLI para Kotlin: Clikt, kotlinx-cli, picocli — visão geral e comparação
Moshi para Kotlin: guia completo com exemplos práticos
Trabalhando com Apache Kafka em C++: bibliotecas e exemplos