O Redis Cluster no Node.js distribui chaves entre múltiplos nós e oferece failover para parte das falhas. Em vez de concentrar todo o dataset em uma única instância, o cluster divide 16.384 hash slots entre masters e usa réplicas para substituir nós indisponíveis.
Essa arquitetura exige um cliente cluster-aware, um modelo de chaves compatível e entendimento das garantias de consistência. Operações com várias chaves só funcionam quando todas pertencem ao mesmo slot, e writes confirmados ainda podem ser perdidos em cenários específicos devido à replicação assíncrona.
Neste guia, você aprenderá a conectar Node.js com ioredis, usar hash tags, tratar MOVED e ASK, configurar timeouts, testar failover, fazer resharding e evitar hotspots.
Como o Redis Cluster funciona?
A documentação oficial de escalabilidade com Redis Cluster explica que as chaves são distribuídas em 16.384 slots. Cada master é responsável por um conjunto, e réplicas podem ser promovidas quando um master falha.
O cluster precisa de pelo menos três masters para o modelo de quorum. Uma implantação comum usa três masters e três réplicas, distribuídos entre hosts ou zonas diferentes.
Quando usar Redis Cluster?
- O dataset não cabe confortavelmente em uma única instância.
- O throughput exige múltiplos masters.
- A aplicação tolera sharding por chave.
- Operações multi-key podem ser modeladas por slot.
- A equipe consegue operar failover e resharding.
Se o dataset cabe em um nó e a prioridade é apenas failover, Redis Sentinel pode ser mais simples.
Instalando o cliente
npm install ioredisO ioredis oferece suporte a cluster, pipeline, reconexão e redirecionamentos. Consulte a documentação do ioredis correspondente à versão instalada.
Criando a conexão
import Redis from 'ioredis';
const redis = new Redis.Cluster([
{ host: 'redis-1.internal', port: 6379 },
{ host: 'redis-2.internal', port: 6379 },
{ host: 'redis-3.internal', port: 6379 }
], {
redisOptions: {
username: process.env.REDIS_USERNAME,
password: process.env.REDIS_PASSWORD,
tls: {}
},
scaleReads: 'slave',
slotsRefreshTimeout: 2000,
slotsRefreshInterval: 10_000
});Os startup nodes servem apenas para descobrir a topologia. O cliente atualiza o mapa de slots após conectar.
Eventos de conexão
redis.on('connect', () => logger.info('Redis Cluster conectado'));
redis.on('ready', () => logger.info('Redis Cluster pronto'));
redis.on('error', error => logger.error({ error }, 'Erro no Redis Cluster'));
redis.on('node error', (error, address) => {
logger.warn({ error, address }, 'Erro em nó Redis');
});Não registre senha, certificados ou comandos com dados sensíveis.
Hash slots
O slot é calculado com CRC16 da chave módulo 16.384. O cliente envia diretamente ao master responsável. Quando a topologia muda, o servidor pode responder MOVED ou ASK, e o cliente atualiza ou redireciona a operação.
Hash tags
O conteúdo entre chaves define a parte usada no hash:
user:{42}:profile
user:{42}:sessions
user:{42}:preferencesAs três chaves ficam no mesmo slot e podem participar de operações multi-key. Escolha a tag para distribuir carga; usar {global} em tudo criaria um único hotspot.
Operações multi-key
Este comando pode falhar com CROSSSLOT:
await redis.mget('user:42', 'user:43');Com hash tag comum:
await redis.mget(
'cart:{tenant-7}:items',
'cart:{tenant-7}:coupon'
);As chaves precisam pertencer ao mesmo agregado lógico. Não force dados sem relação ao mesmo slot somente para facilitar um comando.
Transactions
const tx = redis.multi();
tx.set('order:{123}:status', 'paid');
tx.incr('order:{123}:version');
const result = await tx.exec();Todos os comandos da transação devem usar o mesmo slot. Redis transactions não oferecem rollback de lógica como bancos relacionais.
Lua scripts
Scripts que acessam várias chaves também exigem o mesmo slot:
const script = `
local current = redis.call('GET', KEYS[1])
if current == ARGV[1] then
return redis.call('SET', KEYS[1], ARGV[2])
end
return 0
`;
await redis.eval(
script,
1,
'lock:{payment-9}',
oldToken,
newToken
);Leitura em réplicas
scaleReads: 'slave' distribui reads, mas réplicas podem estar atrasadas. Não use para read-after-write quando a aplicação precisa ler imediatamente o valor gravado.
Para sessões, locks, limites e estados críticos, prefira master. Para caches tolerantes a atraso, réplicas podem reduzir carga.
Consistência
Redis Cluster usa replicação assíncrona. Um master pode confirmar uma escrita e falhar antes de a réplica recebê-la. A réplica promovida não terá esse valor.
O comando WAIT reduz a janela:
await redis.set('payment:{9}:status', 'confirmed');
const replicas = await redis.wait(1, 1000);Mesmo assim, Redis Cluster não oferece consistência forte em todos os cenários. Não use cache como única fonte de verdade de pagamentos ou pedidos. Veja Transações PostgreSQL no Node.js.
Timeouts
const redis = new Redis.Cluster(nodes, {
redisOptions: {
connectTimeout: 3000,
commandTimeout: 1000,
maxRetriesPerRequest: 1
},
clusterRetryStrategy(times) {
return Math.min(100 + times * 200, 2000);
}
});Retries ilimitados transformam indisponibilidade em requisições presas. Defina orçamento por operação e fallback explícito.
Retries e idempotência
Uma conexão pode cair depois de o servidor executar um comando e antes de o cliente receber a resposta. Repetir INCR ou uma publicação pode duplicar o efeito. Use operações idempotentes, tokens e scripts quando necessário.
Consulte Idempotência em APIs Node.js.
Pipeline
const pipeline = redis.pipeline();
for (const product of products) {
pipeline.set(
`product:{${product.tenantId}}:${product.id}`,
JSON.stringify(product),
'EX',
300
);
}
const results = await pipeline.exec();O cliente distribui comandos pelos nós. Pipeline reduz round trips, mas lotes gigantes aumentam memória e latência.
Hotspots
Uma chave popular continua em um único master. Cluster distribui chaves, não uma chave individual. Detecte:
- slots com mais memória;
- comandos por nó;
- latência por master;
- big keys;
- hot keys;
- tags que concentram tenants.
Cache stampede
Mais shards não evitam que milhares de requisições regenerem a mesma chave. Use request coalescing, jitter e stale-while-revalidate. Veja Cache Stampede no Node.js.
Resharding
Redis move slots entre masters enquanto o cluster continua atendendo. Clientes recebem redirecionamentos temporários. Execute em períodos controlados, limite taxa e monitore latência.
redis-cli --cluster reshard redis-1.internal:6379Depois:
redis-cli --cluster check redis-1.internal:6379Adicionando um nó
redis-cli --cluster add-node \
new-node.internal:6379 \
redis-1.internal:6379Um novo master inicia sem slots. Faça rebalance ou resharding antes de esperar distribuição.
Failover
Quando a maioria dos masters reconhece uma falha, uma réplica elegível pode ser promovida. Durante a eleição, parte das operações falha. Clientes precisam tolerar erros transitórios sem esconder indisponibilidade prolongada.
Failover manual
Para manutenção, execute no nó réplica:
CLUSTER FAILOVERO failover manual procura sincronizar a réplica antes da promoção, reduzindo risco de perda.
Rede
Cada nó usa a porta de cliente e a cluster bus port. Todos os nós precisam se alcançar pelos endereços anunciados. NAT e remapeamento incorreto de portas quebram descoberta.
Kubernetes
Use um operador ou chart maduro, anti-affinity, volumes persistentes, PodDisruptionBudget e DNS estável. Não trate um StatefulSet com seis Pods como cluster funcional sem bootstrap e gestão de slots.
TLS e ACL
Configure TLS, usuários com ACL mínima e rotação. Separe credenciais de administração das usadas pela aplicação. Veja Gestão de Segredos no Node.js.
Shutdown da aplicação
async function shutdown() {
await redis.quit();
}
process.on('SIGTERM', shutdown);Integre ao graceful shutdown do servidor e dos workers. Consulte Graceful Shutdown no Node.js.
Observabilidade
Monitore:
- estado do cluster e cobertura de slots;
- masters e réplicas;
- replication lag;
- failovers;
- MOVED e ASK;
- latência por comando;
- memória por nó;
- evictions e expirations;
- conexões e erros do cliente.
Testes de falha
Em ambiente controlado:
- mantenha uma carga com reads e writes;
- encerre um master;
- meça indisponibilidade;
- confirme promoção;
- valide valores críticos;
- reinicie o nó antigo;
- verifique a nova topologia.
Erros comuns
- Cliente standalone: não acompanha MOVED e slots.
- Multi-key sem hash tag: recebe CROSSSLOT.
- Uma tag global: todo tráfego concentra em um master.
- Reads em réplicas críticas: a aplicação lê dados atrasados.
- Redis como fonte transacional: failover pode perder writes.
- Retries ilimitados: APIs ficam presas.
- Porta de cluster bloqueada: nós não formam quorum.
- Sem teste de resharding: manutenção causa surpresa.
Conclusão
O Redis Cluster no Node.js oferece sharding automático por slots e failover entre masters e réplicas. Um cliente cluster-aware mantém o mapa de slots e processa redirecionamentos durante mudanças.
Modele chaves e hash tags com cuidado, limite operações multi-key e entenda a consistência assíncrona. Monitore hotspots, slots e replicação, teste failover e mantenha dados transacionais em um sistema apropriado. Assim, o cluster escala throughput sem esconder os compromissos de um sistema distribuído.



