Introdução ao cache em Kotlin
No desenvolvimento moderno em Kotlin, a performance das aplicações muitas vezes esbarra na velocidade de acesso aos dados. Cache é uma técnica de armazenamento temporário de dados frequentemente solicitados em um armazenamento rápido, o que permite reduzir o tempo de resposta e diminuir a carga em bancos de dados ou APIs externas. Para desenvolvedores Kotlin, três abordagens principais estão disponíveis: o uso de sistemas externos Redis e Memcached, além de soluções embutidas (in-memory cache).
Neste artigo, vamos detalhar cada uma delas, fornecer exemplos práticos de código em Kotlin e ajudar você a escolher a opção ideal para o seu projeto. O material será útil tanto para iniciantes quanto para desenvolvedores experientes que buscam otimizar suas aplicações.
1. Cache embutido em Kotlin (In-Memory)
O cache embutido é a maneira mais simples de acelerar a aplicação sem configurar serviços externos. Ele é implementado usando coleções padrão do Kotlin ou bibliotecas especializadas, como Caffeine ou Guava Cache.
1.1. Cache simples com HashMap
Um exemplo básico — usar ConcurrentHashMap para armazenar dados:
import java.util.concurrent.ConcurrentHashMap
class SimpleCache<K, V> { private val cache = ConcurrentHashMap<K, V>()
fun get(key: K): V? = cache[key]
fun put(key: K, value: V) { cache[key] = value }
fun remove(key: K) = cache.remove(key)
fun clear() = cache.clear()}
// Exemplo de usofun main() { val cache = SimpleCache<String, String>() cache.put("user:1", "Alice") println(cache.get("user:1")) // Saída: Alice}Essa abordagem é simples, mas não suporta remoção automática de dados expirados (TTL) e pode causar vazamentos de memória.
1.2. Cache avançado com Caffeine
Caffeine é uma biblioteca de alto desempenho para cache na JVM, ideal para Kotlin. Ela suporta TTL, evacuação automática e estatísticas.
import com.github.benmanes.caffeine.cache.Caffeineimport java.util.concurrent.TimeUnit
fun main() { val cache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) // TTL 10 minutos .maximumSize(100) // Máximo de 100 entradas .recordStats() // Ativar estatísticas .build<String, String>()
cache.put("session:123", "token_abc") println(cache.getIfPresent("session:123")) // Saída: token_abc
// Estatísticas de uso val stats = cache.stats() println("Acertos: ${stats.hitCount()}, Erros: ${stats.missCount()}")}O cache embutido é excelente para microsserviços single-thread ou pequenos, onde não é necessária sincronização entre várias instâncias da aplicação.
2. Cache com Redis em Kotlin
Redis é um armazenamento de dados in-memory frequentemente usado como cache distribuído. Ele suporta estruturas de dados complexas (strings, listas, hashes, conjuntos) e possui mecanismos embutidos de TTL e persistência.
2.1. Conectando Redis ao Kotlin
Para trabalhar com Redis em Kotlin, as bibliotecas mais comuns são Lettuce (assíncrona) ou Jedis (síncrona). Vejamos um exemplo com Jedis:
// build.gradle.ktsdependencies { implementation("redis.clients:jedis:5.1.0")}
import redis.clients.jedis.JedisPooled
fun main() { val jedis = JedisPooled("localhost", 6379)
// Definir valor com TTL de 60 segundos jedis.setex("user:42", 60, "Bob")
// Obter valor val user = jedis.get("user:42") println("Usuário: $user") // Saída: Usuário: Bob
// Usar hashes jedis.hset("user:42:profile", mapOf( "n