Cache em Go: Redis, Memcached e soluções embutidas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
```html

Cache em Go: Redis, Memcached e soluções embutidas



Cache é uma das ferramentas chave para melhorar o desempenho de aplicações web e serviços. No ecossistema Go (Golang), o desenvolvedor tem acesso tanto a sistemas de cache externos (Redis, Memcached) quanto a soluções embutidas como sync.Map ou as bibliotecas bigcache e freecache. Neste artigo, analisaremos os prós e contras de cada abordagem, forneceremos exemplos de código e ajudaremos você a escolher a ferramenta ideal para o seu projeto.



1. Cache embutido: sync.Map e map com mutex



Go oferece primitivas básicas para criar cache diretamente na memória da aplicação. A maneira mais simples é usar um map comum com um mutex para segurança em concorrência.



Exemplo: cache simples thread-safe



package main

import ( "fmt" "sync" "time")

type Cache struct { mu sync.RWMutex items map[string]interface{}}

func NewCache() *Cache { return &Cache{ items: make(map[string]interface{}), }}

func (c *Cache) Set(key string, value interface{}) { c.mu.Lock() defer c.mu.Unlock() c.items[key] = value}

func (c *Cache) Get(key string) (interface{}, bool) { c.mu.RLock() defer c.mu.RUnlock() val, ok := c.items[key] return val, ok}

func main() { cache := NewCache() cache.Set("user:1", "Alice") val, _ := cache.Get("user:1") fmt.Println(val) // Alice}


Para cenários mais complexos, Go fornece sync.Map — um mapa concorrente otimizado, mais adequado para casos onde as chaves são escritas uma vez e lidas muitas vezes.



Quando usar cache embutido?

  • Micro-cache (durante uma única requisição ou sessão).
  • Aplicações singleton sem arquitetura distribuída.
  • Simplicidade — não é necessário configurar serviços externos.


Desvantagens: ausência de invalidação automática, tamanho limitado (depende da memória da aplicação), sem persistência.



2. BigCache e FreeCache: soluções leves in-memory



As bibliotecas bigcache e freecache resolvem o problema de memória limitada e GC (coleta de lixo). Elas usam buffers pré-alocados e minimizam a carga no garbage collector do Go.



Exemplo com BigCache



package main

import ( "fmt" "github.com/allegro/bigcache/v3" "time")

func main() { cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(10 * time.Minute)) cache.Set("mykey", []byte("myvalue")) val, _ := cache.Get("mykey") fmt.Println(string(val)) // myvalue}


Exemplo com FreeCache



package main

import ( "fmt" "github.com/coocood/freecache")

func main() { cache := freecache.NewCache(100 * 1024) // 100 KB cache.Set([]byte("key"), []byte("value"), 60) // TTL 60 seg val, _ := cache.Get([]byte("key")) fmt.Println(string(val)) // value}


Ambas as bibliotecas suportam TTL (tempo de vida) e remoção automática de entradas antigas. BigCache é melhor para grandes volumes de dados (centenas de gigabytes), FreeCache para cenários com operações frequentes de escrita/leitura.



3. Redis: cache distribuído para produção



Redis é a escolha mais popular para cache em projetos Go. Ele funciona como um servidor separado, suporta estruturas de dados complexas, persistência e clusterização.



Conectando Redis em Go



package main

import ( "context" "fmt" "github.com/redis/go-redis/v9")

func main() { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, })

err := rdb.Set(ctx, "key", "value", 0).Err() if err != nil { panic(err) }

val, err := rdb.Get(ctx, "key").Result() if err != nil { panic(err) } fmt.Println("key", val)}


Redis é ideal para aplicações distribuídas, cache compartilhado entre múltiplas instâncias e cenários que exigem recursos avançados como filas ou pub/sub.

```

Blogs

Book Recommendations