Redis 7: Novidades e Configuração Detalhada

Introdução ao Redis

O Redis (Remote Dictionary Server) é um sistema de armazenamento de estruturas de dados de código aberto, geralmente utilizado em memória. Ele pode funcionar como um banco de dados, cache de alto desempenho ou até mesmo um intermediário de mensagens. Suas estruturas de dados versáteis incluem Strings, Hashes, Lists, Sets, Sorted Sets, entre outras.

As principais aplicações do Redis abrangem:

  1. Caching distribuído para acelerar o acesso a dados.
  2. Persistência assíncrona de dados da memória para o disco, sem comprometer a disponibilidade do serviço.
  3. Mecanismos de mitigação para problemas comuns de cache, como cache penetration, cache breakdown e cache avalanche.
  4. Implementação de bloqueios distribuídos.
  5. Utilização como uma fila de mensagens simples.

Instalação

Instalação no Linux

A instalação do Redis em ambientes Linux é a mais comum para cenários de produção. Antes de iniciar, certifique-se de que o compilador GCC esteja instalado (versão 4.8 ou superior).

gcc -v                  # Verificar a versão do GCC
sudo yum -y install gcc-c++  # Instalar as bibliotecas C++ (para sistemas baseados em CentOS/RHEL)

1. Baixe o pacote tar.gz do site oficial do Redis e extraia-o para um diretório de sua escolha, por exemplo, /opt.

wget https://download.redis.io/releases/redis-7.0.9.tar.gz
tar -zxvf redis-7.0.9.tar.gz -C /opt
cd /opt/redis-7.0.9

2. Compile e instale o Redis:

make && sudo make install

Após a instalação, os executáveis do Redis (redis-server, redis-cli, etc.) geralmente são colocados em /usr/local/bin.

3. Crie um diretório para suas configurações e copie o arquivo de configuração padrão:

sudo mkdir /etc/redis
sudo cp redis.conf /etc/redis/redis7_main.conf

4. Edite o arquivo de configuração /etc/redis/redis7_main.conf para ajustar os parâmetros essenciais:

sudo vim /etc/redis/redis7_main.conf

  • Altere daemonize no para daemonize yes para que o Redis rode como um serviço em segundo plano.
  • Altere protected-mode yes para protected-mode no para permitir conexões externas.
  • Comente ou altere bind 127.0.0.1 para permitir que o Redis aceite conexões de qualquer IP (bind 0.0.0.0) ou um IP específico.
  • Defina uma senha para maior segurança em ambientes de produção, adicionando requirepass SuaSenhaForteAqui.

5. Inicie o serviço Redis usando o arquivo de configuração personalizado:

redis-server /etc/redis/redis7_main.conf

6. Verifique se o Redis está em execução:

ps -ef | grep redis-server | grep -v grep

7. Conecte-se ao cliente Redis:

# Conexão direta com senha (pode exibir aviso de segurança)
redis-cli -a SuaSenhaForteAqui -p 6379

# Conexão e autenticação manual
redis-cli -p 6379
auth SuaSenhaForteAqui

# Conexão e autenticação silenciosa
redis-cli -a SuaSenhaForteAqui -p 6379 2>/dev/null

Após a conexão, digite ping. Se a resposta for PONG, a conexão foi bem-sucedida. Para sair, use quit.

Para desligar o servidor Redis a partir do cliente:

redis-cli -p 6379 -a SuaSenhaForteAqui shutdown

Instalação via Docker

Para ambientes de desenvolvimento ou testes rápidos, a instalação via Docker é uma opção conveniente. Consulte a documentação oficial do Docker Hub para a imagem do Redis.

docker pull redis:7
docker run --name meu-redis -p 6379:6379 -d redis:7 redis-server --appendonly yes --requirepass "MinhaSenhaSecreta"

Recursos do Redis 7

Principais Tipos de Dados

O Redis oferece uma gama rica de tipos de dados:

  • Strings: Valores binariamente seguros, com tamanho máximo de 512 MB. Suportam operações de incremento/decremento e concatenação.
  • Lists: Listas duplamente encadeadas, suportando até 4 bilhões de elementos. Ideais para filas e pilhas.
  • Hashes: Mapas de campos e valores, perfeitos para representar objetos.
  • Sets: Coleções desordenadas de strings únicas. Úteis para operações de união, intersecção e diferença.
  • Sorted Sets (ZSets): Coleções de strings únicas, onde cada membro possui um score associado, permitindo a ordenação.
  • Geospatial (GEO): Armazena coordenadas de latitude e longitude para membros, permitindo buscas por distância.
  • HyperLogLog: Estrutura probabilística para estimar a cardinalidade de um conjunto, usando uma quantidade mínima de memória.
  • Bitmaps: Representam arrays de bits, eficientes para armazenamento de estados binários (ex: presença/ausência).
  • Bitfield: Permite manipular múltiplos campos de bits em uma única operação.
  • Streams: Um tipo de dado semelhante a um log de eventos, suportando grupos de consumidores e persistência. Ideal para filas de mensagens mais complexas.

Comandos Essenciais de Chave

As chaves no Redis são case-sensitive.

# Consulta de chaves
KEYS *                     # Retorna todas as chaves no banco de dados atual
EXISTS minha_chave         # Verifica se a chave existe (1 se sim, 0 se não)
TYPE minha_chave           # Retorna o tipo de dado associado à chave
EXPIRE minha_chave 60      # Define um tempo de expiração de 60 segundos para a chave
TTL minha_chave            # Retorna o tempo restante de expiração em segundos (-1 para sem expiração, -2 para inexistente/expirada)

# Exclusão de chaves
DEL minha_chave            # Exclui uma ou mais chaves
UNLINK minha_chave         # Exclusão assíncrona (não bloqueante)

# Operações em bancos de dados
SELECT 2                   # Seleciona o banco de dados número 2 (padrão é 0, de 0 a 15)
MOVE minha_chave 1         # Move a chave 'minha_chave' para o banco de dados 1
DBSIZE                     # Retorna o número de chaves no banco de dados atual
FLUSHDB                    # Limpa todas as chaves do banco de dados atual
FLUSHALL                   # Limpa todas as chaves de todos os bancos de dados (USE COM CAUTELA!)

# Exclusão em lote via pipeline (Exemplo em Linux)
redis-cli -a SuaSenhaForteAqui KEYS "prefixo_*" | xargs redis-cli -a SuaSenhaForteAqui DEL

Strings

Strings são o tipo de dado mais básico no Redis.

# Definição e recuperação de valores
SET produto:101 nome "Notebook Gamer" EX 30    # Define uma string com expiração de 30 segundos
SET produto:102 preco 1500.00 KEEPTTL        # Altera o valor, mantendo o TTL existente
GET produto:101                            # Recupera o valor da chave

# Múltiplas operações
MSET item:a "Valor A" item:b "Valor B"   # Define múltiplos pares chave-valor
MGET item:a item:b item:c                # Recupera múltiplos valores
MSETNX item:d "Valor D" item:e "Valor E" # Define múltiplos valores apenas se todas as chaves não existirem

# Manipulação de strings
GETRANGE produto:101 0 7                   # Obtém um substring do valor
STRLEN produto:101                         # Retorna o comprimento da string
APPEND produto:101 " Ultra"                # Anexa uma string ao valor existente

# Operações numéricas (o valor deve ser um número)
INCR contador:visitas                      # Incrementa o valor em 1
INCRBY contador:visitas 10                 # Incrementa o valor em 10
DECR contador:estoque                      # Decrementa o valor em 1
DECRBY contador:estoque 5                  # Decrementa o valor em 5

# Bloqueio distribuído (Exemplo de SETNX)
# SETNX e EXPIRE são geralmente combinados em scripts Lua ou comandos atômicos como SET key value NX EX seconds
SETNX lock:recurso "token_aleatorio"       # Define a chave apenas se ela não existir
EXPIRE lock:recurso 10                     # Define expiração para o bloqueio (geralmente feito atomicamente)

# GETSET
GETSET ultimo:acesso "novo_horario"        # Define um novo valor e retorna o valor antigo

Lists

As Lists são estruturas ordenadas que permitem adicionar e remover elementos de ambos os lados.

# Adição de elementos
LPUSH historico:compras "Item C" "Item B" "Item A"  # Adiciona elementos à esquerda (ordem LIFO)
RPUSH tarefas:pendentes "Tarefa 1" "Tarefa 2"     # Adiciona elementos à direita (ordem FIFO)

# Recuperação de elementos
LRANGE historico:compras 0 -1                       # Recupera todos os elementos
LINDEX historico:compras 0                          # Recupera o elemento no índice 0
LLEN historico:compras                              # Retorna o número de elementos

# Remoção de elementos
LPOP historico:compras                              # Remove e retorna o elemento mais à esquerda
RPOP tarefas:pendentes                              # Remove e retorna o elemento mais à direita
LREM historico:compras 1 "Item B"                 # Remove 1 ocorrência do valor "Item B" da esquerda para a direita
LREM historico:compras 0 "Item A"                 # Remove todas as ocorrências do valor "Item A"

# Outras operações
LTRIM historico:compras 0 1                         # Mantém apenas os elementos nos índices 0 e 1
RPOPLPUSH fila:origem fila:destino                  # Move o último elemento da fila:origem para o início de fila:destino
LSET historico:compras 1 "Item Modificado"          # Altera o elemento no índice 1
LINSERT historico:compras BEFORE "Item B" "Item Novo" # Insere "Item Novo" antes de "Item B"

Cenário de Uso: Registro de atividades recentes. Para registrar os 50 últimos itens que um usuário visualizou:

LPUSH usuario:123:visualizados item_id_x
LTRIM usuario:123:visualizados 0 49
LRANGE usuario:123:visualizados 0 9 # Recuperar os 10 últimos itens

Hashes

Hashes são mapas de strings para strings, ideais para armazenar objetos.

# Operações de Hash
HSET usuario:456 nome "Ana Silva" email "ana@exemplo.com"  # Define múltiplos campos e valores
HGET usuario:456 nome                                     # Obtém o valor de um campo
HLEN usuario:456                                          # Retorna o número de campos
HEXISTS usuario:456 telefone                              # Verifica se um campo existe
HKEYS usuario:456                                         # Retorna todos os nomes dos campos
HVALS usuario:456                                         # Retorna todos os valores dos campos
HGETALL usuario:456                                       # Retorna todos os campos e seus valores
HDEL usuario:456 email                                    # Exclui um campo
HINCRBY usuario:456 pontuacao 10                          # Incrementa um valor numérico em um campo

Sets

Sets são coleções desordenadas de membros únicos.

# Operações de Set
SADD usuarios:ativos "usuario1" "usuario2" "usuario3" "usuario2" # Adiciona membros (duplicados são ignorados)
SMEMBERS usuarios:ativos                                     # Retorna todos os membros
SISMEMBER usuarios:ativos "usuario1"                         # Verifica a existência de um membro
SREM usuarios:ativos "usuario3"                               # Remove membros
SCARD usuarios:ativos                                        # Retorna o número de membros
SRANDMEMBER usuarios:ativos 2                                # Retorna 2 membros aleatórios sem removê-los
SPOP usuarios:ativos 1                                       # Remove e retorna 1 membro aleatório
SMOVE usuarios:ativos usuarios:inativos "usuario1"           # Move um membro entre sets

# Operações de conjunto
SADD setA "a" "b" "c"
SADD setB "c" "d" "e"
SDIFF setA setB                                              # Diferença: A - B (membros em A, mas não em B)
SINTER setA setB                                             # Interseção: A ∩ B (membros em ambos)
SUNION setA setB                                             # União: A ∪ B (todos os membros únicos)
SINTERCARD 2 setA setB LIMIT 1                               # Conta o tamanho da interseção sem retornar os membros

Cenário de Uso: Sistema de sorteio ou loteria.

# Adicionar participantes
SADD sorteio:participantes "id_usuario_1" "id_usuario_2" "id_usuario_3"
# Contar participantes
SCARD sorteio:participantes
# Sortear 2 vencedores (sem remoção)
SRANDMEMBER sorteio:participantes 2
# Sortear 1 vencedor (com remoção)
SPOP sorteio:participantes 1

Sorted Sets (ZSets)

ZSets são sets onde cada membro possui uma pontuação (score) que define sua ordem.

# Operações de ZSet
ZADD placar:jogo 100 "jogadorA" 150 "jogadorB" 75 "jogadorC" # Adiciona membros com scores
ZRANGE placar:jogo 0 -1 WITHSCORES                          # Lista membros em ordem crescente de score
ZREVRANGE placar:jogo 0 2 WITHSCORES                        # Lista os 3 melhores (ordem decrescente)
ZRANGEBYSCORE placar:jogo 80 120 WITHSCORES                # Membros com score entre 80 e 120
ZSCORE placar:jogo "jogadorA"                               # Obtém o score de um membro
ZCARD placar:jogo                                           # Retorna o número de membros
ZREM placar:jogo "jogadorC"                                 # Remove um membro
ZINCRBY placar:jogo 20 "jogadorA"                           # Incrementa o score de um membro
ZCOUNT placar:jogo 50 100                                   # Conta membros em um intervalo de score
ZRANK placar:jogo "jogadorA"                                # Retorna o índice (rank) de um membro
ZREVRANK placar:jogo "jogadorA"                             # Retorna o índice (rank) inverso de um membro

Bitmaps

Bitmaps permitem manipular bits individuais em uma string.

# Operações de Bitmap
SETBIT usuario:status:202301 0 1      # Dia 1: usuário presente
SETBIT usuario:status:202301 1 0      # Dia 2: usuário ausente
SETBIT usuario:status:202301 5 1      # Dia 6: usuário presente
GETBIT usuario:status:202301 0        # Status do dia 1
STRLEN usuario:status:202301          # Tamanho da string em bytes
BITCOUNT usuario:status:202301        # Conta o número de bits definidos como 1

# Operações lógicas (AND, OR, XOR, NOT)
BITOP AND resultado:and key1 key2
BITOP OR resultado:or key1 key2
BITOP XOR resultado:xor key1 key2
BITOP NOT resultado:not key_unica

Cenário de Uso: Controle de presença/assinatura mensal.

# Registrar presença do usuário 1 no dia 15 do mês 2 (índice 14)
SETBIT presenca:user:1:202302 14 1
# Verificar presença do usuário 1 no dia 15
GETBIT presenca:user:1:202302 14
# Contar dias de presença do usuário 1 no mês 2
BITCOUNT presenca:user:1:202302

HyperLogLog

Uma estrutura para estimativa de cardinalidade (contagem de elementos únicos) com memória constante.

# Operações de HyperLogLog
PFADD visitantes:diarios "ip1" "ip2" "ip3" "ip1" # Adiciona elementos para contagem
PFCOUNT visitantes:diarios                      # Retorna a estimativa de elementos únicos (cardinalidade)
PFADD visitantes:diarios:alt "ip3" "ip4"
PFMERGE visitantes:totais visitantes:diarios visitantes:diarios:alt # Combina múltiplas contagens
PFCOUNT visitantes:totais

Cenário de Uso: Contagem de visitantes únicos em um site (UV - Unique Visitors).

Geospatial (GEO)

Armazena coordenadas de latitude e longitude, permitindo buscas baseadas em localização.

# Operações GEO
GEOADD cidades:brasil -46.6396 -23.5558 "São Paulo" -43.1729 -22.9068 "Rio de Janeiro"
GEOPOS cidades:brasil "São Paulo" "Rio de Janeiro" # Retorna as coordenadas de membros
GEODIST cidades:brasil "São Paulo" "Rio de Janeiro" km # Distância entre dois pontos em KM
GEORADIUS cidades:brasil -46.6 23.5 100 km WITHCOORD WITHDIST COUNT 5 ASC # Busca em raio
GEORADIUSBYMEMBER cidades:brasil "São Paulo" 200 km WITHCOORD WITHDIST # Busca em raio por membro

Streams

Streams oferecem funcionalidades de fila de mensagens mais avançadas, com persistência e grupos de consumidores.

# Exemplo de uso básico de Stream
XADD eventos:sistema * nivel info mensagem "Início da aplicação"
XADD eventos:sistema * nivel warn mensagem "Recurso esgotado"
XRANGE eventos:sistema - +                            # Lê todos os eventos
XREAD COUNT 2 STREAMS eventos:sistema 0               # Lê os 2 primeiros eventos a partir do ID 0

Bitfield

Permite a manipulação atômica de campos de bits arbitrários em uma string.

# Exemplo Bitfield
BITFIELD meu_estado SET u8 #0 255 INCRBY u8 #8 1 OVERFLOW WRAP # Define um byte, incrementa outro

Persistência de Dados

O Redis oferece diferentes estratégias para persistir dados, garantindo que não sejam perdidos em caso de falha.

RDB (Redis Data base)

O RDB realiza "snapshots" (cópias instantâneas) do conjunto de dados do Redis em intervalos de tempo configuráveis. O arquivo gerado é chamado dump.rdb.

  • Vantagens: Ótimo para recuperação de desastres em larga escala, mais rápido para inicialização e recuperação do que AOF, e compactação de dados.
  • Desvantagens: Perda potencial de dados entre o último snapshot e uma eventual falha. Operações de I/O intensivas para conjuntos de dados muito grandes.

Configuração no redis7_main.conf:

# Salva o banco de dados se pelo menos 1 chave mudou em 3600 segundos (1 hora)
# OU se pelo menos 100 chaves mudaram em 300 segundos (5 minutos)
# OU se pelo menos 10000 chaves mudaram em 60 segundos (1 minuto)
save 3600 1 300 100 60 10000

# Para desabilitar o RDB:
# save ""

# Diretório para salvar o arquivo RDB
dir /var/lib/redis

# Nome do arquivo RDB
dbfilename snapshot.rdb

Para criar um snapshot manualmente, use SAVE (bloqueante) ou BGSAVE (não bloqueante) no cliente Redis.

AOF (Append-Only File)

O AOF registra cada operação de escrita recebida pelo servidor em um arquivo de log. Ao reiniciar, o Redis recria o estado do conjunto de dados executando essas operações.

  • Vantagens: Maior durabilidade dos dados (menos perda em caso de falha), o arquivo AOF é um log linear fácil de entender.
  • Desvantagens: Arquivo AOF geralmente maior que RDB, pode ser mais lento para inicializar/recuperar.

Configuração no redis7_main.conf:

# Habilita o AOF
appendonly yes

# Nome do arquivo AOF
appendfilename "operacoes.aof"

# Estratégia de sincronização do AOF (fsync)
# always: sincroniza a cada operação de escrita (mais lento, mais seguro)
# everysec: sincroniza a cada segundo (padrão, bom equilíbrio)
# no: deixa o SO decidir (menos seguro)
appendfsync everysec

# Redis 7 introduz um diretório dedicado para arquivos AOF, melhorando a organização:
appenddirname "aof_logs" # Ex: /var/lib/redis/aof_logs/

# Reescrita automática do AOF (compactação)
# Aciona a reescrita se o tamanho do AOF duplicou e é maior que 64MB
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

Para reescrever o AOF manualmente, use BGREWRITEAOF no cliente Redis.

Se um arquivo AOF estiver corrompido, ele pode ser reparado usando:

redis-check-aof --fix /var/lib/redis/aof_logs/operacoes.aof.1.incr.aof

Persistência Híbrida (RDB + AOF)

A partir do Redis 4.0, é possível combinar RDB e AOF. Durante uma reescrita do AOF, o Redis salva o estado atual do banco de dados em formato RDB e, em seguida, anexa as operações de escrita incrementais no formato AOF.

Configuração no redis7_main.conf:

aof-use-rdb-preamble yes

Quando habilitado, em caso de reinício, o Redis carregará o "preâmbulo RDB" rapidamente e depois aplicará as operações AOF incrementais.

Transações

As transações no Redis permitem agrupar uma sequência de comandos que serão executados de forma atômica.

  • Não garantem isolamento completo (outras operações podem intervir entre MULTI e EXEC, mas não durante a execução do EXEC).
  • Não têm capacidade de rollback em caso de erros de tipo de dados ou semânticos.
  • Garantem exclusividade: todos os comandos são executados sequencialmente sem interrupções de outros clientes.
MULTI                # Inicia a transação
SET chave:itemA "valor1"
SET chave:itemB "valor2"
INCR chave:contador  # Comando que pode falhar se chave:contador não for numérica
EXEC                 # Executa todos os comandos enfileirados

Se um erro de sintaxe ocorrer antes de EXEC, a transação inteira será abortada. Se um erro ocorrer durante a execução (após EXEC), apenas o comando inválido falhará, e os outros comandos válidos serão executados.

Para abortar uma transação antes de EXEC:

MULTI
SET chave:temp "teste"
DISCARD              # Aborta a transação

WATCH para Controle Otimista

O comando WATCH permite monitorar chaves para garantir que não sejam modificadas por outro cliente antes da execução de uma transação. Se uma chave monitorada for alterada, a transação falhará (retornando nil em EXEC).

WATCH saldo:user:101      # Monitora a chave do saldo
GET saldo:user:101        # Cliente 1 lê o saldo (ex: 500)
MULTI
DECRBY saldo:user:101 100
EXEC                      # Se saldo:user:101 foi modificado por outro cliente, EXEC retorna (nil)

UNWATCH remove todos os monitores de chaves.

Pipelining

O pipelining é uma otimização de rede que permite ao cliente enviar vários comandos ao servidor Redis em uma única requisição TCP, sem esperar a resposta de cada comando. O servidor processa todos os comandos e envia as respostas de volta em lote.

# Exemplo de comandos em um arquivo (cmds.txt)
SET chave:p1 "valor_pipeline_1"
GET chave:p1
INCR contador:p

# Executando via pipeline
cat cmds.txt | redis-cli -a SuaSenhaForteAqui --pipe

A principle diferença entre pipeline e transações é que o pipeline é uma otimização de rede, enquanto as transações garantem atomicidade e ordenação. Um pipeline pode incluir transações.

Publicação/Assinatura (Pub/Sub)

O Pub/Sub do Redis permite que clientes se inscrevam em canais e recebam mensagens publicadas nesses canais.

# Cliente 1 (Assinante)
SUBSCRIBE canal:noticias canal:alertas

# Cliente 2 (Publicador)
PUBLISH canal:noticias "Ultimas Notícias: Previsão do tempo atualizada."
PUBLISH canal:alertas "Alerta: Servidor X com alta latência!"

# Assinatura por padrão (wildcard)
PSUBSCRIBE canal:*

# Cancelar assinatura
UNSUBSCRIBE canal:noticias
PUNSUBSCRIBE canal:*

O Pub/Sub do Redis é um mecanismo "fire-and-forget": as mensagens não são persistidas. Se um assinante não estiver conectado no momento da publicação, ele perderá a mensagem.

Replicação Master-Slave

A replicação permite que instâncias do Redis (replicas/slaves) sejam cópias exatas de outras instâncias (master). Isso é fundamental para alta disponibilidade e escalabilidade de leitura.

# No servidor slave
REPLICAOF <ip_do_master> <porta_do_master>

Após configurada, a réplica sincroniza os dados do master e continua recebendo atualizações. Para promover uma réplica a master (parando a replicação):

REPLICAOF NO ONE

**Configuração de Exemplo (Master):**Crie /etc/redis/redis_master.conf:

daemonize yes
bind 0.0.0.0
protected-mode no
port 6379
requirepass SuaSenhaMestre
dbfilename dump6379.rdb
appendonly yes
appendfilename "appendonly6379.aof"

**Configuração de Exemplo (Replica):**Crie /etc/redis/redis_replica.conf:

daemonize yes
bind 0.0.0.0
protected-mode no
port 6380
requirepass SuaSenhaReplica
dbfilename dump6380.rdb
appendonly yes
appendfilename "appendonly6380.aof"
replicaof 127.0.0.1 6379
masterauth SuaSenhaMestre # Senha para se autenticar no master

Inicie os servidores com seus respectivos arquivos de configuração. Use INFO REPLICATION no cliente Redis para verificar o status.

Sentinel

O Redis Sentinel é um sistema de monitoramento para instâncias do Redis. Ele gerencia a alta disponibilidade do Redis, monitorando instâncias master e réplicas, e realizando a failover automático quando um master falha.

Um sistema Sentinel geralmente consiste em várias instâncias Sentinel em diferentes máquinas.

Configuração de Exemplo (/etc/redis/sentinel_26379.conf):

daemonize yes
port 26379
dir /var/lib/redis-sentinel
logfile "/var/log/redis/sentinel_26379.log"
# Monitora um master chamado 'meu_cluster_principal' no IP 127.0.0.1 porta 6379
# O '2' indica que pelo menos 2 sentinels devem concordar sobre a falha do master
sentinel monitor meu_cluster_principal 127.0.0.1 6379 2
sentinel auth-pass meu_cluster_principal SuaSenhaMestre
# Tempo em milissegundos que um master deve ficar inacessível para ser considerado objetivamente down
sentinel down-after-milliseconds meu_cluster_principal 30000

Para iniciar um Sentinel:

redis-sentinel /etc/redis/sentinel_26379.conf

Recomenda-se um número ímpar de Sentinels (geralmente 3 ou 5).

Cluster

O Redis Cluster permite distribuir dados automaticamente entre múltiplos nós Redis, oferecendo escalabilidade horizontal e alta disponibilidade. Ele particiona o conjunto de dados em 16384 "slots" de hash, que são distribuídos entre os nós master.

Métodos de Particionamento em Cluster:

  • Particionamento por Hash: Utiliza o módulo do hash da chave para determinar qual nó armazenará a chave. Dificulta a expansão/redução do cluster.
  • Hash Consistente: Mapeia chaves e nós para um anel hash, minimizando o rebalanceamento de dados em caso de adição/remoção de nós. Pode levar a uma distribuição não uniforme.
  • Slots de Hash: O Redis Cluster utiliza 16384 slots de hash. Cada chave é mapeada para um slot, e esses slots são distribuídos uniformemente entre os nós master do cluster.

Configuração de um Cluster (Exemplo 3 Masters, 3 Replicas)

Serão necessárias 6 instâncias Redis, cada uma com sua própria configuração.

Passo 1: Configurar cada instância Redis (Exemplo para a porta 7000):

Crie arquivos de configuração como /etc/redis/cluster/redis_cluster_7000.conf:

port 7000
daemonize yes
bind 0.0.0.0
protected-mode no
dir /var/lib/redis/cluster-data/7000
logfile "/var/log/redis/cluster_7000.log"
pidfile /var/run/redis_cluster_7000.pid
dbfilename dump7000.rdb
appendonly yes
appendfilename "appendonly7000.aof"
requirepass SuaSenhaCluster
masterauth SuaSenhaCluster

# Habilitar o modo cluster
cluster-enabled yes
# Arquivo de configuração do cluster (gerado automaticamente)
cluster-config-file nodes-7000.conf
# Tempo limite para um nó ser considerado inacessível
cluster-node-timeout 5000

# Se um cluster estiver incompleto, pode continuar servindo requisições (padrão é yes)
# cluster-require-full-coverage no

Repita este processo para as portas 7001, 7002, 7003, 7004 e 7005, ajustando os nomes dos arquivos e diretórios.

Passo 2: Iniciar todas as instâncias Redis:

redis-server /etc/redis/cluster/redis_cluster_7000.conf
redis-server /etc/redis/cluster/redis_cluster_7001.conf
# ... e assim por diante para todas as 6 instâncias

Passo 3: Criar o Cluster:

Use o comando redis-cli --cluster create para formar o cluster. O parâmetro --cluster-replicas 1 especifica que cada master terá uma réplica.

redis-cli -a SuaSenhaCluster --cluster create --cluster-replicas 1 \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

Confirme a criação quando solicitado (digite yes).

Passo 4: Verificar o status do Cluster:

Conecte-se a qualquer nó do cluster usando a flag -c para modo cluster:

redis-cli -a SuaSenhaCluster -p 7000 -c

Dentro do cliente, use:

CLUSTER NODES # Visualiza a topologia do cluster (masters, replicas, slots)
CLUSTER INFO  # Informações gerais sobre o cluster

Passo 5: Testar o Cluster:

SET meu_item "valor_distribuido" # O cliente redirecionará para o nó correto
GET meu_item
CLUSTER KEYSLOT meu_item       # Descobre qual slot a chave pertence

Expansão do Cluster: Adicionar um novo Master e sua Replica

1. Crie e inicie duas novas instâncias Redis (ex: 7006, 7007) com configurações de cluster similares.

2. Adicione o novo nó 7006 como master ao cluster existente (usando um nó existente como ponto de contato):

redis-cli -a SuaSenhaCluster --cluster add-node 127.0.0.1:7006 127.0.0.1:7000

3. Redistribua os slots para o novo master 7006:

redis-cli -a SuaSenhaCluster --cluster reshard 127.0.0.1:7000

Siga as instruções interativas: defina quantos slots mover (ex: 4096), qual nó receberá os slots (o ID do nó 7006) e de quais nós os slots serão migrados (all para distribuir de todos os masters existentes).

4. Adicione o nó 7007 como réplica do novo master 7006:

redis-cli -a SuaSenhaCluster --cluster add-node 127.0.0.1:7007 127.0.0.1:7006 --cluster-slave --cluster-master-id <ID_DO_NO_7006>

O ID do nó 7006 pode ser encontrado com CLUSTER NODES.

Redução do Cluster: Remover um Master e sua Replica

1. Obtenha os IDs dos nós 7006 (master) e 7007 (replica) usando CLUSTER NODES.

2. Remova a réplica 7007 do cluster:

redis-cli -a SuaSenhaCluster --cluster del-node 127.0.0.1:7007 <ID_DO_NO_7007>

3. Migre os slots do master 7006 para outros masters no cluster:

redis-cli -a SuaSenhaCluster --cluster reshard 127.0.0.1:7000

Siga as instruções interativas: defina quantos slots mover (todos os slots do 7006), qual nó receberá os slots (um dos masters restantes), e o ID do nó de onde os slots serão migrados (ID do nó 7006).

4. Remova o master 7006 do cluster:

redis-cli -a SuaSenhaCluster --cluster del-node 127.0.0.1:7006 <ID_DO_NO_7006>

Integração com Spring Boot

A integração do Redis com aplicações Spring Boot é comumente feita através do spring-boot-starter-data-redis.

Conexão com Instância Única

1. Adicione a dependência no pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. Configure o application.properties:

spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=SuaSenhaRedis
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

3. Crie uma classe de configuração para RedisTemplate:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisClientConfig {

    @Bean
    public RedisTemplate<String, Object> customRedisTemplate(LettuceConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        // Configuração de serialização para chaves e valores
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        // Configuração de serialização para chaves e valores de Hash
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        template.afterPropertiesSet();
        return template;
    }
}

4. Exemplo de uso em um serviço:

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class DataService {

    @Resource
    private RedisTemplate<String, Object> customRedisTemplate;

    public void salvarDados(String chave, String valor) {
        customRedisTemplate.opsForValue().set(chave, valor);
    }

    public String obterDados(String chave) {
        return (String) customRedisTemplate.opsForValue().get(chave);
    }
}

Conexão com Redis Cluster

Para conectar a um cluster Redis, o application.properties precisa ser modificado:

spring.redis.password=SuaSenhaCluster
spring.redis.cluster.max-redirects=5 # Número máximo de redirecionamentos de slots
# Lista de nós do cluster (qualquer nó inicial será suficiente para o Lettuce descobrir a topologia completa)
spring.redis.cluster.nodes=127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003,127.0.0.1:7004,127.0.0.1:7005
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

# Configurações para atualização adaptativa da topologia do cluster (Lettuce)
spring.redis.lettuce.cluster.refresh.adaptive=true
spring.redis.lettuce.cluster.refresh.period=5s # Período de atualização em segundos

O Lettuce (cliente padrão do Spring Data Redis) é capaz de descobrir a topologia completa do cluster a partir de qualquer nó fornecido. As propriedades spring.redis.lettuce.cluster.refresh.adaptive e spring.redis.lettuce.cluster.refresh.period são importantes para que o cliente se adapte a mudanças na topologia do cluster (como failovers ou adições/remoções de nós) de forma dinâmica.

Tags: Redis Redis7 DataStructures Persistence Clustering

Publicado em 7-13 13:33