Cache em Go (Golang): Redis, in-memory e outras soluções
Cache é uma das estratégias-chave para melhorar o desempenho e reduzir a carga no banco de dados em aplicações Go. Neste artigo, abordaremos as principais abordagens e bibliotecas para implementar cache: desde soluções simples in-memory até cache distribuído com Redis. Você aprenderá quando escolher cada ferramenta e como organizar o cache corretamente em projetos Go.
1. Recursos nativos: map e sync.Map
A maneira mais simples de fazer cache em Go é usar um map comum com mutex ou o sync.Map thread-safe. Essas abordagens são adequadas para projetos pequenos ou protótipos onde não é necessária uma política complexa de invalidação.
Exemplo com sync.Map:
package main
import ( "fmt" "sync")
type Cache struct { data sync.Map}
func (c *Cache) Set(key string, value interface{}) { c.data.Store(key, value)}
func (c *Cache) Get(key string) (interface{}, bool) { return c.data.Load(key)}
func main() { cache := &Cache{} cache.Set("user:1", "Alice") if val, ok := cache.Get("user:1"); ok { fmt.Println("Encontrado:", val) }}Vantagens: simplicidade, zero dependências.
Desvantagens: sem TTL, sem limpeza automática, memória ilimitada.
2. Cache in-memory com TTL: freecache
Freecache é uma biblioteca rápida de cache in-memory com suporte a TTL (tempo de vida da entrada). Ela usa uma arquitetura segmentada para minimizar bloqueios e gerenciar a memória de forma eficiente.
Instalação:
go get github.com/coocood/freecacheExemplo de uso:
package main
import ( "fmt" "github.com/coocood/freecache")
func main() { // Cria um cache de 100 MB cache := freecache.NewCache(100 * 1024 * 1024)
// Define um valor com TTL de 10 segundos cache.Set([]byte("mykey"), []byte("myvalue"), 10)
// Obtém o valor if val, err := cache.Get([]byte("mykey")); err == nil { fmt.Println("Valor:", string(val)) } else { fmt.Println("Chave não encontrada ou expirada") }}Vantagens: limpeza automática por TTL, baixo consumo de CPU, suporte a grandes volumes de dados.
Desvantagens: apenas para um único processo (não distribuído).
3. BigCache — alternativa ao freecache
BigCache é outra biblioteca in-memory popular, otimizada para armazenar um grande número de entradas (milhões) com tempo de acesso mínimo. Ela também suporta TTL e evacuação automática de dados antigos.
Exemplo:
package main
import ( "fmt" "github.com/allegro/bigcache/v3" "time")
func main() { config := bigcache.Config{ Shards: 1024, LifeWindow: 10 * time.Minute, CleanWindow: 5 * time.Minute, MaxEntriesInWindow: 1000 * 10 * 60, MaxEntrySize: 500, Verbose: true, }
cache, _ := bigcache.NewBigCache(config) cache.Set("mykey", []byte("bigcache value")) val, _ := cache.Get("mykey") fmt.Println(string(val))}Vantagens: alta performance com grande número de chaves, configuração flexível.
Desvantagens: assim como o freecache — cache local.
4. Cache distribuído com Redis e go-redis
Para sistemas distribuídos, onde várias instâncias da aplicação precisam de um cache unificado, utiliza-se o Redis. O cliente mais popular para Go é o go-redis (anteriormente go-redis/redis).
Instalação:
go get github.com/redis/go-redis/v9Exemplo de cache básico:
Também na biblioteca
Event Bus e o padrão Observer em Java: implementação de arquitetura fracamente acoplada
Rate Limiting em Swift: gerenciamento de frequência de requisições em iOS/macOS
Envio de Email em PHP: PHPMailer, mail() e alternativas