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

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

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



Cache é uma das ferramentas chave para melhorar o desempenho de aplicações web e microsserviços. Em Go (Golang), existem várias abordagens: desde estruturas de dados embutidas simples até sistemas distribuídos poderosos como Redis e Memcached. Neste artigo, vamos analisar as principais opções de cache, suas vantagens, desvantagens e fornecer exemplos práticos de código.



Por que o cache é necessário em Go?

Go é conhecido por sua velocidade e eficiência, mas mesmo nele frequentemente encontramos gargalos: consultas lentas ao banco de dados, APIs externas ou cálculos pesados. O cache permite:

  • Reduzir a carga no banco de dados e serviços externos.
  • Diminuir o tempo de resposta da API (latência).
  • Economizar recursos do servidor (CPU, memória).
  • Aumentar a tolerância a falhas durante interrupções temporárias.

A escolha da solução específica depende da arquitetura da aplicação: monolítica ou microsserviços, requisitos de consistência de dados, volume de cache e orçamento.



Cache embutido em Go

Para cenários simples (por exemplo, cache de dados dentro de um único processo), os recursos embutidos do Go são adequados. Eles não exigem a instalação de serviços externos e são ideais para aplicações pequenas.



1. sync.Map

sync.Map é um map thread-safe da biblioteca padrão do Go. Adequado para cache que raramente é atualizado e frequentemente lido. Exemplo:

package main

import ( "fmt" "sync")

func main() { var cache sync.Map

// Salva dados cache.Store("user_1", "Alice") cache.Store("user_2", "Bob")

// Lê dados if val, ok := cache.Load("user_1"); ok { fmt.Println("Found:", val) }

// Remove cache.Delete("user_2")}

Prós: simplicidade, sem dependências externas, thread-safe. Contras: sem TTL (tempo de vida), sem limpeza automática, limitado a um único processo.



2. Pacote go-cache

A biblioteca popular github.com/patrickmn/go-cache adiciona suporte a TTL e limpeza automática. Exemplo:

package main

import ( "fmt" "time" "github.com/patrickmn/go-cache")

func main() { // Cria cache com tempo de vida de 5 minutos e limpeza a cada 10 minutos c := cache.New(5*time.Minute, 10*time.Minute)

// Salva com TTL c.Set("session_token", "abc123", cache.DefaultExpiration)

// Obtém token, found := c.Get("session_token") if found { fmt.Println("Token:", token) }

// Remove c.Delete("session_token")}

Prós: TTL, simplicidade de integração, limpeza automática. Contras: dados armazenados na memória de um único processo, não adequado para sistemas distribuídos.



Redis: cache distribuído para Go

Redis é a solução mais popular para cache em Go. Ele funciona como um servidor separado, suporta estruturas de dados complexas (strings, hashes, listas, conjuntos) e tem excelente suporte em Go através do driver go-redis.



Conexão e operações básicas

package main

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

func main() { ctx := context.Background()

// Conexão ao Redis rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // sem senha DB: 0, })

// Salva string com TTL (1 hora) err := rdb.Set(ctx, "key", "value", 3600*time.Second).Err() if err != nil { panic(err) }

// Lê val, err := rdb.Get(ctx, "key").Result() if err != nil { fmt.Println("Key not found") } else { fmt.Println("Value:", val) }

// Remove rdb.Del(ctx, "key")}

Blogs

Book Recommendations