Redis Sentinel: alta disponibilidade self-hosted

Redis Sentinel monitora instâncias do Redis e executa failover automático quando o primary fica offline, promovendo uma replica a primary sem intervenção manual. Para aplicações que não podem perder conexão com o Redis (sessões, filas), Sentinel é a solução self-hosted de alta disponibilidade.

Arquitetura: Primary + Replica + Sentinel

Como o Redis Sentinel funciona:

bash
# Arquitetura mínima de Sentinel (3 nós):
# ┌──────────────┐    replicação    ┌──────────────┐
# │  Primary     │ ──────────────→  │  Replica     │
# │  :6379       │                  │  :6380       │
# └──────────────┘                  └──────────────┘
#         ↑                                ↑
#         │         monitoramento          │
# ┌───────┴────────────────────────────────┴───────┐
# │  Sentinel 1   Sentinel 2   Sentinel 3          │
# │  :26379       :26380       :26381               │
# └────────────────────────────────────────────────┘

# Com 3 Sentinels (quorum = 2):
# - Se o primary ficar offline e 2/3 Sentinels concordarem:
#   → Um Sentinel é eleito líder
#   → Escolhe a replica mais atualizada
#   → Promove a replica a primary
#   → Reconfigura outros Sentinels
#   → Notifica os clientes (PUBLISH __sentinel__:hello)

# Para VPS única: rodar primary, replica e 3 Sentinels localmente
# Para alta disponibilidade real: primary e replica em VPS diferentes

Configurar Primary e Replica

Configuração do Redis em modo primary-replica:

bash
# redis-primary.conf:
port 6379
bind 127.0.0.1
requirepass SUA_SENHA_REDIS
masterauth SUA_SENHA_REDIS   # senha para autenticação entre instâncias

# Persistência:
appendonly yes
appendfsync everysec
save 3600 1

# redis-replica.conf:
port 6380
bind 127.0.0.1
requirepass SUA_SENHA_REDIS
masterauth SUA_SENHA_REDIS

# Apontar para o primary:
replicaof 127.0.0.1 6379

# Replica é somente leitura por padrão:
replica-read-only yes

# Iniciar as instâncias:
redis-server /etc/redis/redis-primary.conf --daemonize yes
redis-server /etc/redis/redis-replica.conf --daemonize yes

# Verificar replicação:
redis-cli -p 6379 -a SUA_SENHA_REDIS INFO replication
# role:master
# connected_slaves:1
# slave0:ip=127.0.0.1,port=6380,state=online,offset=1234,lag=0

Configurar Sentinels

Três instâncias Sentinel para atingir o quorum:

bash
# sentinel-1.conf (repetir para sentinel-2.conf e sentinel-3.conf com portas 26380, 26381):
port 26379
daemonize yes
logfile /var/log/redis/sentinel-1.log

# Monitorar o primary (nome, IP, porta, quorum):
sentinel monitor mymaster 127.0.0.1 6379 2

# Autenticação:
sentinel auth-pass mymaster SUA_SENHA_REDIS

# Quanto tempo até considerar o primary offline (ms):
sentinel down-after-milliseconds mymaster 5000

# Timeout do failover:
sentinel failover-timeout mymaster 60000

# Quantas replicas sincronizam simultaneamente durante failover:
sentinel parallel-syncs mymaster 1

# Iniciar os 3 Sentinels:
redis-sentinel /etc/redis/sentinel-1.conf
redis-sentinel /etc/redis/sentinel-2.conf
redis-sentinel /etc/redis/sentinel-3.conf

# Verificar status do Sentinel:
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL slaves mymaster
redis-cli -p 26379 SENTINEL sentinels mymaster

# Simular falha do primary:
redis-cli -p 6379 -a SUA_SENHA_REDIS DEBUG SLEEP 10
# Após ~5s: Sentinel promove a replica automaticamente

Integrar Node.js com Redis Sentinel

Configurar ioredis para conectar via Sentinel:

typescript
// npm install ioredis

import Redis from 'ioredis'

// Conectar via Sentinel — ioredis descobre o primary automaticamente:
const redis = new Redis({
  sentinels: [
    { host: '127.0.0.1', port: 26379 },
    { host: '127.0.0.1', port: 26380 },
    { host: '127.0.0.1', port: 26381 },
  ],
  name: 'mymaster',          // nome configurado no sentinel.conf
  password: process.env.REDIS_PASSWORD,
  sentinelPassword: process.env.REDIS_PASSWORD,

  // Reconectar automaticamente após failover:
  maxRetriesPerRequest: 3,
  enableReadyCheck: true,
  lazyConnect: false,

  // Timeout agressivo para detectar failover rápido:
  connectTimeout: 2000,
  commandTimeout: 3000,
})

// Evento de failover:
redis.on('error', (err) => console.error('Redis error:', err))
redis.on('reconnecting', (ms) => console.log('Redis reconectando em', ms, 'ms'))

// O cliente reconecta automaticamente ao novo primary após failover
// A janela de indisponibilidade é ~10-15s (tempo do Sentinel eleger o líder)

// Usar normalmente:
await redis.set('sessao:123', JSON.stringify(dados), 'EX', 3600)
const sessao = await redis.get('sessao:123')

Docker Compose com Redis Sentinel

Stack completa containerizada com primary, replica e Sentinels:

yaml
# docker-compose.yml — Redis HA com Sentinel:
services:
  redis-primary:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD} --masterauth ${REDIS_PASSWORD} --appendonly yes
    ports:
      - "127.0.0.1:6379:6379"
    volumes:
      - redis_primary:/data

  redis-replica:
    image: redis:7-alpine
    command: >
      redis-server
      --requirepass ${REDIS_PASSWORD}
      --masterauth ${REDIS_PASSWORD}
      --replicaof redis-primary 6379
      --replica-read-only yes
    ports:
      - "127.0.0.1:6380:6379"
    depends_on:
      - redis-primary

  sentinel-1: &sentinel
    image: redis:7-alpine
    command: >
      sh -c "echo 'sentinel monitor mymaster redis-primary 6379 2
      sentinel auth-pass mymaster ${REDIS_PASSWORD}
      sentinel down-after-milliseconds mymaster 5000
      sentinel failover-timeout mymaster 60000
      sentinel parallel-syncs mymaster 1' > /tmp/sentinel.conf
      && redis-sentinel /tmp/sentinel.conf"
    depends_on:
      - redis-primary
      - redis-replica

  sentinel-2:
    <<: *sentinel
  sentinel-3:
    <<: *sentinel

volumes:
  redis_primary:

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

Sentinel: alta disponibilidade com failover automático para uma única instância de dados, primary + replicas. Todos os nós têm os mesmos dados. Ideal para datasets que cabem em um único servidor. Redis Cluster: sharding horizontal, divide os dados entre múltiplos nós (slots de hash). Cada nó tem apenas uma parte dos dados. Ideal para datasets > memória de um único servidor. Para a maioria das VPS: Sentinel é suficiente.

Quorum, para executar o failover, a maioria dos Sentinels deve concordar. Com 2 Sentinels: se a rede partir, não há maioria e o failover nunca acontece (split-brain). Com 3 Sentinels: quorum de 2, se um ficar offline, os outros 2 concordam e executam o failover. Para ambientes de VPS única: os 3 Sentinels podem rodar na mesma máquina (proteção contra crash do Redis, não contra falha do servidor).

down-after-milliseconds (5.000ms padrão) + tempo de eleição do Sentinel líder (~2s) + tempo de promoção da replica (~2s) = ~10-15 segundos no total. Durante esse período, writes falham. A aplicação Node.js com ioredis enfileira os comandos e reexecuta após o failover. Para reduzir: diminua down-after-milliseconds para 2.000ms, mas cuidado com falsos positivos por lentidão de rede.

Sim, mas protege apenas contra falha do processo Redis (crash, OOM killer), não contra falha da VPS inteira. Para produção crítica: coloque primary e replica em VPS diferentes (mesmo datacenter). Para desenvolvimento ou aplicações com tolerância a alguns minutos de downtime: Sentinel em VPS única já é muito melhor que Redis sem failover.

Antes da manutenção: redis-cli -p 26379 SENTINEL failover mymaster, força o failover manualmente para a replica (menos trauma para a aplicação). Após a manutenção na ex-primary: reinicie-a; ela volta como replica automaticamente. Para reverter: outro failover manual. Alternativamente: pause o Sentinel antes da manutenção (redis-cli SENTINEL SUSPEND mymaster) e reative depois.