Introdução
O Redis é sistema de armazenamento de dados e tem, dentre muitas funcionalidades, a capacidade de operar como um banco de dados NoSQL, baseado no princípio chave-valor. O acrônimo Redis vem de Remote Dictionary Server (ou servidor de dicionário remoto). O Redis é capaz de suportar diferentes tipos de dados, e uma de suas principais vantagens é a sua performance, pois todos os dados de um servidor Redis residem na memória RAM da máquina hospedeira. Além disso, quando usado como banco de dados, permite a persistência dos dados em disco.
No presente tutorial, criamos um exemplo de como utilizar o Redis como banco de dados.
Docker image
Este tutorial utiliza a versão 7.0-alpine
da imagem do Redis. Verifique mais detalhes sobre a imagem do Redis em Docker Hub.
Criando servidor Redis
Para que uma instância do Redis seja criada, é necessário o uso de um arquivo de configuração. Exemplos de arquivos estão disponíveis na documentação oficial do Redis (Documentação sobre as configurações). Deve-se utilizar o arquivo de configuração de acordo com a versão da imagem escolhida.
Arquivo de configuração
Crie um arquivo chamado redis.conf
e copie as informações do arquivo de configuração padrão, fornecidas na documentação oficial.
Ou, caso deseje fazê-lo via linha de comando, escreva a seguinte linha no seu terminal:
curl "https://raw.githubusercontent.com/redis/redis/<version>/redis.conf" > redis.conf
Onde <version>
, na URL especificada, deve ser substituído pela versão escolhida do Redis.
Configurações
Altere a linha do arquivo de configuração, que contém a palavra requirepass
e, adicione uma senha.
requirepass "anyPassword"
Durante os testes que realizei, ao tentar subir a instância do Redis, me era apresentado a seguinte mensagem de aviso:
Warning: Could not create server TCP listening socket ::1:6379: bind: Address not available
Esse erro ocorre pois o servidor Redis não tem acesso as interfaces de rede necessárias. Para solucionar esse problema, é preciso alterar a linha que contém a palavra bind
, na seção de rede, do arquivo de configuração do servidor. Pesquise e reescreva a linha do seguinte modo:
bind 0.0.0.0
Configurações Docker
Criando uma rede, que será usada para comunicação com o servidor Redis.
docker network create redis
A partir da rede criada anteriormente e do arquivo de configurações do Redis, podemos criar o container:
docker run -it --rm --name redis --net redis -v ${PWD}:/etc/redis/ redis:7.0-alpine redis-server /etc/redis/redis.conf
Listando cada opção e flag usada anteriormente:
-it
: indica que desejamos um terminal interativo;--rm
: usado para remover o container após a sua finalização;--name
: usado para atribuir um nome ao container;--net
: informa a rede a ser usada;-v
: usado para montar um volume do tipo bind, entre o diretório atual da máquina e o container.
No final da linha temos o caminho, já no container, para o arquivo de configuração usado no servidor.
Criando um Volume
Para que os dados possam persistir, será necessário o uso de um volume. Que neste caso, seja criado e gerenciado pelo próprio Docker. Nós podemos criar o volume e manipula-lo por meio da CLI do Docker.
docker volume create redis
Após a criação do volume, caso a instância criada anteriormente ainda esteja em execução, finalize-a, e depois crie outra instância, mas agora montado o volume criado anteriormente.
docker run -it --rm --name redis --net redis -v ${PWD}:/etc/redis/ -v redis:/data/ redis:7.0-alpine redis-server /etc/redis/redis.conf
A segunda flag -v
é usada para montar o novo volume, que será usada para persistência dos dados.
Exemplo em Go
Com o Go instalado, crie um novo módulo com:
go mod init client
Um arquivo chamado go.mod
deve ser gerado.
O código a seguir é um simples exemplo de como utilizar o Redis como um banco de dados. Crie um arquivo (aqui eu chamarei o arquivo de client.go
) e adicione o seguinte código:
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
var ctx = context.Background()
func main() {
:= redis.NewClient(&redis.Options{
rdb : "redis:6379",
Addr: "anyPassword",
Password: 0,
DB})
// Consultando se a chave já existe
:= "keyName"
myKey , err := rdb.Get(ctx, myKey).Result()
myValue// Caso não exista
if err == redis.Nil {
// Cria a chave
.Printf("A chave %s não existe.\n", myKey)
fmt= rdb.Set(ctx, myKey, "anyValue", 0).Err()
err if err != nil {
.Println("Erro ao criar par chave-valor.")
fmt}
// Caso seja apresentado outro erro
} else if err != nil {
panic(err)
// Caso a chave tenha sido encontrada
} else {
.Printf("Chave = %s e valor = %s.\n", myKey, myValue)
fmt}
}
Para lidar com as dependências, rode:
go get
O Go deve gerar um arquivo chamado go.sum
, que é um arquivo que guarda informações da dependências.
Criando o container do client
Para executar o programa client, devemos utilizar a imagem do golang. Neste caso eu utilizei a versão 1.20-alpine
. Ao rodar a linha abaixo, é necessário que o diretório atual seja o diretório do código fonte do programa client.
docker run -ti --net redis -v ${PWD}:/client -w /client golang:1.20-alpine
Foi utilizado a flag -w
ela indica o diretório de trabalho adotado. Caso você queira verificar os arquivos disponíveis no diretório do container, rode um ls
e você deverá ver os arquivos criados anteriormente.
Dentro do container, rode:
go install
Assim as dependências serão instaladas. Logo em seguida, compile o client rodando:
go build client.go
E, para finalizar, execute o client com: ./client
.
A saída esperada é:
A chave keyName não existe.
Caso você tente executar o client novamente, você deverá ver a seguinte mensagem.
Chave = keyName e valor = anyValue.
Encerre a instância do servidor do Redis e cria uma nova. Ao executar o client novamente, você verá que o par chave-valor ainda existe.