Integração de Redis em Go utilizando a biblioteca Redigo

O ecossistema Go oferece diversas bibliotecas para interação com o Redis, sendo a Redigo uma das mais consolidadas e amplamente utilizadas devido à sua interface baseada em comandos puros do Redis e suporte robusto para recursos avançados.

Instalação e Configuração

Para começar a utilizar a biblioteca em seu projeto, instale o pacote via terminal:

go get github.com/gomodule/redigo/redis

Estabelecendo Conexão

A interface central da biblioteca é a Conn. A conexão é estabelecida através da função Dial, e é fundamental garantir o fechamento da mesma para evitar vazamento de recursos.

package main

import (
    "fmt"
    "github.com/gomodule/redigo/redis"
)

func main() {
    // Conectando ao servidor local
    conexao, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Printf("Falha na conexão: %v\n", err)
        return
    }
    defer conexao.Close()
}

Operações Básicas de String e Expiração

O método Do é utilizado para enviar comandso genéricos ao Redis. Para converter o retorno para tipos específicos do Go, a Redigo fornece funções auxiliares como redis.String.

// Definindo uma chave com valor e tempo de expiração
_, err = conexao.Do("SET", "sessao:usuario:101", "ativo")
_, err = conexao.Do("EXPIRE", "sessao:usuario:101", 3600) // 1 hora

// Recuperando o valor
status, err := redis.String(conexao.Do("GET", "sessao:usuario:101"))
if err == nil {
    fmt.Printf("Status da sessão: %s\n", status)
}

Manipulação de Múltiplos Valores (MSET e MGET)

Para otimizar a latência, é possível processar várias chaves em uma única chamada de rede.

// Configuração múltipla
_, err = conexao.Do("MSET", "app:cor", "azul", "app:versao", "2.1.0")

// Leitura múltipla
valores, err := redis.Strings(conexao.Do("MGET", "app:cor", "app:versao"))
for i, v := range valores {
    fmt.Printf("Item %d: %s\n", i, v)
}

Estruturas de Dados: Listas e Hashes

A biblioteca suporta todas as estruturas nativas do Redis. Abaixo, exemplos de manipulação de listas e mapas (hashes).

// Exemplo com Listas (Fila)
conexao.Do("RPUSH", "fila:tarefas", "processar_imagem", "enviar_email")
tarefa, _ := redis.String(conexao.Do("LPOP", "fila:tarefas"))

// Exemplo com Hashes
conexao.Do("HSET", "perfil:1", "username", "dev_golang", "nivel", 5)
nivel, _ := redis.Int(conexao.Do("HGET", "perfil:1", "nivel"))
fmt.Printf("Nível do usuário: %d\n", nivel)

Uso de Pipelining

O Pipelining permite enviar uma sequência de comandos sem esperar pela resposta de cada um individualmente, reduzindo o overhead de rede. Isso é feito através de Send, Flush e Receive.

// Adiciona comandos ao buffer de saída
conexao.Send("SET", "contador:A", 10)
conexao.Send("SET", "contador:B", 20)
conexao.Send("GET", "contador:A")

// Envia o buffer completo para o servidor
conexao.Flush()

// Recebe os resultados na ordem em que foram enviados
conexao.Receive() // Resposta do primeiro SET
conexao.Receive() // Resposta do segundo SET
res, _ := redis.Int(conexao.Receive())
fmt.Printf("Resultado do contador A: %d\n", res)

Modelo de Pub/Sub (Publicação e Assinatura)

Para sistemas orientados a eventos, a Redigo oferece o tipo PubSubConn.

func iniciarInscricao() {
    c, _ := redis.Dial("tcp", "127.0.0.1:6379")
    psc := redis.PubSubConn{Conn: c}
    psc.Subscribe("notificacoes_sistema")

    for {
        switch v := psc.Receive().(type) {
        case redis.Message:
            fmt.Printf("Canal %s: mensagem: %s\n", v.Channel, v.Data)
        case error:
            return
        }
    }
}

func publicarEvento(msg string) {
    c, _ := redis.Dial("tcp", "127.0.0.1:6379")
    c.Do("PUBLISH", "notificacoes_sistema", msg)
}

Transações Atômicas

Transações no Redis garantem que um bloco de comandos seja executado de forma atômica utilizando MULTI e EXEC.

conexao.Send("MULTI")
conexao.Send("INCR", "metricas:acessos")
conexao.Send("INCR", "metricas:vendas")
resultado, err := conexao.Do("EXEC")
if err == nil {
    fmt.Println("Transação concluída com sucesso:", resultado)
}

Conexão Avançada com Parâmetros

Em ambientes produtivos, é comum a necessidade de autenticação e seleção de bases de dados específicas.

func obterConexaoCustomizada() (redis.Conn, error) {
    return redis.Dial("tcp", "10.0.0.50:6379",
        redis.DialPassword("senha_segura"),
        redis.DialDatabase(2),
    )
}

Tags: Redis Golang Redigo backend nosql

Publicado em 9-16 21:36