
Um Valkey sozinho aguenta muita coisa, mas quando cai leva junto o cache, as sessões e as filas da aplicação. O modo cluster resolve os dois problemas de uma vez: divide os dados entre vários primários e deixa uma réplica pronta para assumir cada pedaço quando um servidor morre. Neste guia montamos um cluster com 3 primários e 3 réplicas, derrubamos um primário de propósito e medimos quanto tempo as escritas ficaram paradas. Também adicionamos e removemos nós, ligamos persistência, ACL e TLS, configuramos o serviço com systemd e ligamos o Valkey Admin no cluster. Tudo foi executado de verdade num laboratório em Docker com o Valkey 9.1.2, e as saídas mostradas abaixo saíram desse teste.
O que é o Valkey
Em março de 2024 a Redis Inc. trocou a licença do Redis, que era BSD, por licenças source available. No dia 28 daquele mês a Linux Foundation anunciou o Valkey, um fork criado por mantenedores e colaboradores antigos do projeto a partir do Redis 7.2.4. O Valkey continua com a licença BSD de 3 cláusulas e tem governança aberta. AWS, Google Cloud, Oracle, Ericsson e Snap apoiaram o projeto desde o anúncio. O protocolo continua o mesmo, então clientes e ferramentas feitos para o Redis em geral funcionam sem alteração.
Versões em 23/09/2026, conferidas nas releases do GitHub e na página de download:
- 9.1.2 (31/08/2026): estável atual. É uma release de segurança que corrige dois use-after-free (um deles no estado do interpretador Lua, explorável sem autenticação) e dezenas de bugs, vários deles de cluster e de migração de slots. Atualize.
- 9.0.6 e 8.1.10 (01/09/2026): últimas correções das séries anteriores que ainda recebem suporte.
- 9.2.0-rc1 (16/09/2026): release candidate. Não use em produção.
Novidades das duas últimas versões maiores que mudam a operação de um cluster, segundo os anúncios oficiais do Valkey 9.0 e do Valkey 9.1:
- Atomic Slot Migration (9.0): o resharding passa a mover o slot inteiro, e não mais chave por chave. O nó de origem mantém todos os dados até o fim da migração, o que evita os redirecionamentos intermediários e o travamento com chaves muito grandes. O comando é
CLUSTER MIGRATESLOTS, que usamos mais abaixo. - Bancos numerados no modo cluster (9.0):
SELECT 1passou a funcionar em cluster. No Redis e nas versões anteriores do Valkey, o cluster só aceitava o db 0. - Expiração por campo de hash (9.0): comandos como
HEXPIRE,HSETEXeHGETEX. - Clusters grandes (9.0): o projeto informa escala de até 2.000 nós e mais de 1 bilhão de requisições por segundo.
- ACL por banco de dados (9.1):
ACL SETUSER app ... db=0,1restringe um usuário a alguns bancos. - Lua como módulo (9.1): o Lua saiu do núcleo e pode ser desligado quando não é usado.
- TLS (9.1): recarga automática dos certificados, data de expiração no
INFOe autenticação por SAN URI. - Log em JSON (9.1):
log-format jsonnovalkey.conf. - Memória e desempenho (9.1): strings pequenas usam até 20% menos memória, há um novo modelo de I/O threads e os comandos novos
HGETDELeMSETEX.
Como o cluster funciona
O Valkey Cluster divide o espaço de chaves em 16384 hash slots. O slot de uma chave é CRC16(chave) mod 16384, e cada primário é dono de uma faixa de slots. Com 3 primários, a divisão padrão fica assim: 0–5460, 5461–10922 e 10923–16383. Cada primário tem uma ou mais réplicas, que recebem os dados por replicação assíncrona e ficam prontas para assumir.
- Barramento do cluster (cluster bus): além da porta dos clientes, cada nó abre uma segunda porta TCP, que por padrão é a porta do cliente mais 10000 (16379). Por ela os nós trocam gossip binário, ou seja, PING/PONG com o estado de cada nó, o mapa de slots e os votos de failover.
- Detecção de falha: se um nó fica sem responder por mais de
cluster-node-timeout, quem percebe o marca comoPFAIL(falha provável). Quando a maioria dos primários relata o mesmo, ele viraFAILe essa informação se espalha pelo cluster. - Failover automático: a réplica do primário em
FAILpede votos aos outros primários. Com a maioria dos votos, ela se promove, incrementa o config epoch e passa a servir os slots do primário que caiu. - MOVED: quando o cliente pede uma chave a um nó que não é dono do slot, recebe
MOVED <slot> <ip:porta>. Um cliente cluster-aware atualiza o mapa de slots e vai direto ao nó certo. - ASK: aparece enquanto um slot está migrando e a chave já foi para o destino. O redirecionamento vale só para aquela requisição, e o cliente não atualiza o mapa.
- Hash tags: quando a chave tem
{...}, só o trecho entre chaves entra no cálculo do slot.{pedido:42}:itense{pedido:42}:totalcaem no mesmo slot e podem ser usadas juntas emMSET, transações e scripts.

Cluster ou Sentinel?
As duas opções entregam alta disponibilidade, mas resolvem problemas diferentes:
| Sentinel | Cluster | |
|---|---|---|
| Dados | Um único primário com o dataset inteiro | Dataset dividido entre vários primários (sharding) |
| Escala de escrita | A de um servidor | Cresce com o número de primários |
| Failover | Processos valkey-sentinel separados votam e promovem a réplica |
Os próprios nós votam pelo barramento |
| Cliente | Pergunta ao Sentinel quem é o primário | Precisa entender MOVED/ASK (modo cluster) |
| Comandos multi-chave | Livres | Só com chaves no mesmo slot (hash tags) |
| Bancos numerados | Sim | Sim a partir do Valkey 9.0 |
Se o dataset cabe num servidor e a aplicação depende de muitos comandos multi-chave, o Sentinel é mais simples. Se você precisa de mais memória ou de mais vazão de escrita do que uma máquina entrega, o caminho é o cluster.
Requisitos e portas
- Mínimo de 3 primários. A documentação recomenda 6 nós (3 primários e 3 réplicas), e cada primário deve ficar numa máquina diferente da sua réplica.
- TCP 6379 (clientes e replicação) e TCP 16379 (barramento) abertos entre todos os nós. Os clientes precisam alcançar a 6379 de todos os nós, e não só de um.
- Sem NAT nem remapeamento de portas. O cluster anuncia o próprio IP e a própria porta, e o Docker com
-p 7000:6379quebra os redirecionamentos. No laboratório abaixo usamos uma rede bridge com IP fixo por contêiner e sem publicar portas. Em Kubernetes, usecluster-announce-ip/cluster-announce-hostnameou o Helm chart oficial. - O barramento não autentica mensagens. Pela documentação, a porta 16379 aceita o que chegar. Proteja-a com firewall liberando só os IPs dos nós, ou com mTLS (
tls-cluster yes).
Laboratório com Docker: 6 nós em 5 minutos
O laboratório usa a imagem oficial valkey/valkey:9.1.2 numa rede bridge dedicada, e cada nó recebe um IP fixo. Se precisar de uma revisão sobre contêineres, veja a história do Docker. Comece pelo arquivo de configuração que os seis nós vão compartilhar:
mkdir -p ~/valkey-lab && cd ~/valkey-lab
cat > valkey.conf <<'EOF'
port 6379
bind 0.0.0.0
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
appendfsync everysec
save 900 1 300 10
dir /data
EOF
docker network create --subnet 10.77.77.0/24 valkey-net
for i in 1 2 3 4 5 6; do
docker run -d --name valkey-$i --hostname valkey-$i \
--network valkey-net --ip 10.77.77.1$i \
-v "$PWD/valkey.conf:/usr/local/etc/valkey/valkey.conf:ro" \
valkey/valkey:9.1.2 valkey-server /usr/local/etc/valkey/valkey.conf
done
# contêiner "cliente" na mesma rede, para rodar valkey-cli e testes
docker run -d --name valkey-client --network valkey-net --ip 10.77.77.30 \
valkey/valkey:9.1.2 sleep infinity
O protected-mode no sem senha serve só para o laboratório isolado. A seção de segurança mostra o que muda em produção. Antes de criar o cluster, um nó recém-iniciado recusa escritas:
$ docker exec valkey-1 valkey-cli set foo bar
CLUSTERDOWN Hash slot not served
Crie o cluster com uma réplica por primário:
docker exec valkey-client valkey-cli --cluster create \
10.77.77.11:6379 10.77.77.12:6379 10.77.77.13:6379 \
10.77.77.14:6379 10.77.77.15:6379 10.77.77.16:6379 \
--cluster-replicas 1 --cluster-yes
>>> Performing hash slots allocation on 6 node(s)...
Primary[0] -> Slots 0 - 5460
Primary[1] -> Slots 5461 - 10922
Primary[2] -> Slots 10923 - 16383
Adding replica 10.77.77.15:6379 to 10.77.77.11:6379
Adding replica 10.77.77.16:6379 to 10.77.77.12:6379
Adding replica 10.77.77.14:6379 to 10.77.77.13:6379
...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
CLUSTER INFO e CLUSTER NODES
$ docker exec valkey-client valkey-cli -h 10.77.77.11 cluster info | head -12
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_nodes_pfail:0
cluster_nodes_fail:0
cluster_voting_nodes_pfail:0
cluster_voting_nodes_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
$ docker exec valkey-client valkey-cli -h 10.77.77.11 cluster nodes
63fa7320... 10.77.77.12:6379@16379 master - 0 1790176949000 2 connected 5461-10922
6e304101... 10.77.77.14:6379@16379 slave 5eaf881d... 0 1790176949520 3 connected
4bc5ee75... 10.77.77.15:6379@16379 slave accd0471... 0 1790176949000 1 connected
accd0471... 10.77.77.11:6379@16379 myself,master - 0 0 1 connected 0-5460
57d5706c... 10.77.77.16:6379@16379 slave 63fa7320... 0 1790176948000 2 connected
5eaf881d... 10.77.77.13:6379@16379 master - 0 1790176948818 3 connected 10923-16383
Em cada linha de CLUSTER NODES aparecem o ID do nó, ip:porta@porta-do-barramento, o papel, o primário que ele replica (no caso das réplicas), o config epoch e as faixas de slots. Os IDs foram encurtados aqui. O valkey-cli --cluster check 10.77.77.11:6379 mostra a mesma informação num formato mais fácil de ler e avisa sobre slots abertos ou descobertos.
$ C="docker exec valkey-client valkey-cli"
$ $C -h 10.77.77.11 set usuario:1000 nilton
MOVED 7319 10.77.77.12:6379
$ $C -h 10.77.77.11 cluster keyslot usuario:1000
(integer) 7319
$ $C -c -h 10.77.77.11 set usuario:1000 nilton # -c segue o redirecionamento
OK
$ $C -c -h 10.77.77.11 get usuario:1000
"nilton"
$ $C -c -h 10.77.77.11 mset a 1 b 2
CROSSSLOT Keys in request don't hash to the same slot
$ $C -h 10.77.77.11 cluster keyslot '{pedido:42}:itens'
(integer) 2873
$ $C -h 10.77.77.11 cluster keyslot '{pedido:42}:total'
(integer) 2873
$ $C -c -h 10.77.77.11 mset '{pedido:42}:itens' 3 '{pedido:42}:total' 99.90
OK
O -c não resolve o CROSSSLOT, porque o comando precisa rodar inteiro num único nó. Para carregar dados de teste, o valkey-benchmark tem modo cluster:
docker exec valkey-client valkey-benchmark -h 10.77.77.11 --cluster \
-t set,get -n 100000 -r 100000 -q
for i in 1 2 3; do docker exec valkey-$i valkey-cli dbsize; done
# 34705 / 32366 / 32931 chaves: distribuição equilibrada entre os shards
Failover na prática: derrubando um primário
Para medir o failover, um script no contêiner cliente grava a chave conta:1 a cada 100 ms. A chave fica no slot 3844, que pertence ao primário 10.77.77.11. O script usa valkey-cli -c com timeout de 0,5 s por tentativa e anota quando a primeira escrita falha e quando as escritas voltam:
cat > failover.sh <<'EOF'
#!/bin/bash
# Grava conta:1 (slot 3844) a cada 100 ms e mede quanto tempo as escritas falham.
ms() { date +%s%3N; }
falhou=0; n=0
while :; do
n=$((n+1))
r=$(timeout 0.5 valkey-cli -c -h 10.77.77.12 set conta:1 "$n" 2>&1)
if [ "$r" != "OK" ]; then
[ "$falhou" = 0 ] && falhou=$(ms) && echo "$(date +%T.%3N) primeira falha: ${r:-timeout}"
elif [ "$falhou" != 0 ]; then
echo "$(date +%T.%3N) escrita voltou; indisponivel por $(( $(ms) - falhou )) ms"; exit 0
fi
sleep 0.1
done
EOF
chmod +x failover.sh
docker cp failover.sh valkey-client:/failover.sh
docker exec -d valkey-client bash -c '/failover.sh > /failover.log 2>&1'
sleep 2; date -u +%T.%3N; docker kill valkey-1 # derruba o primário sem aviso
sleep 15; docker exec valkey-client cat /failover.log
Resultado com cluster-node-timeout 5000. O docker kill foi às 15:23:07.013 (UTC):
15:23:07.589 primeira falha: timeout
15:23:13.216 escrita voltou; indisponivel por 5628 ms
O log da réplica valkey-5 mostra a sequência:
15:23:13.076 * FAIL message received from 63fa7320... (10.77.77.12:6379) about accd0471... (10.77.77.11:6379)
15:23:13.076 # Cluster state changed: fail
15:23:13.076 * This is the best ranked replica and can initiate the election immediately.
15:23:13.076 * Starting a failover election for epoch 7, node config epoch is 1
15:23:13.079 * Failover election won: I'm the new primary.
15:23:13.079 * configEpoch set to 7 after successful failover
Entre a morte do primário e a volta das escritas passaram cerca de 6,2 s. Quase todo esse tempo foi o cluster-node-timeout (5 s) somado à propagação do FAIL pelo gossip. A eleição levou 3 ms. Repetimos o teste com o timeout em 2000 ms (CONFIG SET cluster-node-timeout 2000 em todos os nós), derrubando o novo primário. O FAIL saiu 2,99 s depois do kill e as escritas voltaram em cerca de 3,1 s.

Um timeout menor não é de graça. Uma pausa longa de rede ou de disco, como um fork grande para o RDB, pode disparar um failover desnecessário. Entre 2 e 5 segundos é uma faixa razoável em rede local, mas meça no seu ambiente. Depois do failover, o primário antigo volta como réplica do nó promovido:
$ docker start valkey-1
$ docker exec valkey-client valkey-cli -h 10.77.77.12 cluster nodes | grep -E '1[15]:'
accd0471... 10.77.77.11:6379@16379 slave 4bc5ee75... 0 1790177013144 7 connected
4bc5ee75... 10.77.77.15:6379@16379 master - 0 1790177012000 7 connected 0-5460
Para devolver o papel de primário, sem perder escritas, rode CLUSTER FAILOVER na réplica. O failover manual espera a réplica alcançar o offset do primário antes de trocar os papéis. É o procedimento certo para atualizar a versão nó a nó:
docker exec valkey-client valkey-cli -h 10.77.77.11 cluster failover
docker exec valkey-client valkey-cli -h 10.77.77.11 role | head -1 # master
Adicionando nós, rebalance e remoção
Suba dois nós novos com a mesma configuração (valkey-7 em 10.77.77.17 e valkey-8 em 10.77.77.18). Um entra como primário vazio e o outro como réplica dele:
C="docker exec valkey-client valkey-cli"
$C --cluster add-node 10.77.77.17:6379 10.77.77.11:6379
$C --cluster add-node 10.77.77.18:6379 10.77.77.11:6379 --cluster-replica
# sem --cluster-primaries-id, a réplica é associada ao primário com menos réplicas (o novo)
O primário novo entra sem slots. O rebalance distribui os slots por igual, e --cluster-use-empty-primaries é o que faz ele considerar os primários vazios:
$ time $C --cluster rebalance 10.77.77.11:6379 --cluster-use-empty-primaries
>>> Rebalancing across 4 nodes. Total weight = 4.00
Moving 1366 slots from 10.77.77.12:6379 to 10.77.77.17:6379
Moving 1365 slots from 10.77.77.13:6379 to 10.77.77.17:6379
Moving 1365 slots from 10.77.77.11:6379 to 10.77.77.17:6379
real 0m6,472s
$ $C --cluster info 10.77.77.11:6379
10.77.77.11:6379 (accd0471...) -> 26018 keys | 4096 slots | 1 replicas.
10.77.77.17:6379 (7149edd5...) -> 24991 keys | 4096 slots | 1 replicas.
10.77.77.13:6379 (5eaf881d...) -> 24782 keys | 4096 slots | 1 replicas.
10.77.77.12:6379 (63fa7320...) -> 24212 keys | 4096 slots | 1 replicas.
[OK] 100003 keys in 4 primaries.
Para mover uma faixa específica existe o --cluster reshard (--cluster-from, --cluster-to, --cluster-slots). No Valkey 9 também dá para usar a migração atômica direto, e foi assim que esvaziamos o nó 17 antes de removê-lo. O comando é enviado ao nó de origem, com uma faixa por destino:
$ $C -h 10.77.77.17 cluster migrateslots \
slotsrange 0 1364 node accd0471d25a3d53a1a66c41971d01adacdbbe70 \
slotsrange 5461 6826 node 63fa7320b3a4524df08a5925ab94962b08b5c5e0 \
slotsrange 10923 12287 node 5eaf881d4c3e5720ccf7cc369540e57ed00decfe
OK
$ $C -h 10.77.77.17 cluster getslotmigrations # state: success em cada job
Detalhe observado no teste: depois de perder todos os slots, o nó 17 se reconfigurou sozinho como réplica de outro primário. É a migração de réplicas (cluster-allow-replica-migration, ligada por padrão). Com o nó vazio, remova primeiro a réplica e depois o antigo primário:
$C --cluster del-node 10.77.77.11:6379 <id-do-valkey-8>
$C --cluster del-node 10.77.77.11:6379 <id-do-valkey-7>
$C --cluster check 10.77.77.11:6379
# [OK] 100003 keys in 3 primaries. [OK] All 16384 slots covered.
Nenhuma chave se perdeu no vaivém: 100003 antes e 100003 depois. Para o --cluster call, que roda o mesmo comando em todos os nós, veja a pegadinha da seção de troubleshooting.
Persistência: RDB e AOF
No cluster, cada nó persiste só os próprios slots. As opções são as mesmas do Valkey standalone (documentação):
- RDB (
save 900 1 300 10): snapshot periódico, compacto, bom para backup. Pode perder as escritas feitas desde o último snapshot. - AOF (
appendonly yes,appendfsync everysec): registra cada escrita e perde no máximo cerca de 1 s. Desde o Redis 7 o AOF é multiparte: umbase.rdb, umincr.aofe um manifesto.
$ docker exec valkey-1 ls /data /data/appendonlydir
/data:
appendonlydir nodes.conf
/data/appendonlydir:
appendonly.aof.2.base.rdb appendonly.aof.2.incr.aof appendonly.aof.manifest
$ docker restart valkey-1 valkey-2 valkey-3 valkey-4 valkey-5 valkey-6
$ docker exec valkey-client valkey-cli --cluster info 10.77.77.11:6379 | tail -2
[OK] 100003 keys in 3 primaries.
O nodes.conf não é backup de dados. É o estado do cluster (IDs, epochs, slots), escrito pelo próprio Valkey, e não deve ser editado à mão. Guarde junto do backup, mas não o copie para outro nó. Em cache puro dá para desligar os dois (save "" e appendonly no). Nesse caso a réplica é a única cópia, e um nó que reinicia volta vazio e sincroniza tudo de novo.
Segurança: protected-mode, senha, ACL e TLS
protected-mode
Se o usuário default não tem senha e o protected-mode está ligado (padrão), o Valkey só aceita conexões pelo loopback. Um cliente remoto recebe:
DENIED Running in protected mode because protected mode is enabled and no password is set for the default user. In this mode connections are only accepted from the loopback interface. ...
A saída não é desligar a proteção. É definir senha, ou usuários ACL, e manter o bind nos IPs internos.
Senha do cluster e autenticação entre réplica e primário
No cluster, as réplicas também se autenticam no primário, e por isso requirepass precisa andar junto com primaryauth (o antigo masterauth). No laboratório aplicamos as duas com CONFIG SET e reiniciamos uma réplica. Como o arquivo montado era somente leitura, a configuração não persistiu, e a réplica voltou sem primaryauth:
master_link_status:down
# Unexpected reply to PSYNC from primary: -NOAUTH Authentication required.
# PRIMARY aborted replication with an error: NOAUTH Authentication required.
Coloque as duas diretivas no valkey.conf de todos os nós, e não só via CONFIG SET. Com senha, as ferramentas de cluster recebem -a (ou --user/--pass):
valkey-cli -a 'SenhaForte' --no-auth-warning --cluster check 10.77.77.11:6379
ACL por aplicação
As ACLs não são replicadas pelo barramento. Crie o usuário em cada nó, ou mantenha um aclfile igual em todos:
for i in 11 12 13 14 15 16; do
valkey-cli -a 'SenhaForte' --no-auth-warning -h 10.77.77.$i \
ACL SETUSER app on '>S3nhaApp!' '~app:*' '+@read' '+@write' '-@dangerous'
done
$ valkey-cli -c -h 10.77.77.11 --user app --pass 'S3nhaApp!' --no-auth-warning set app:config 1
OK
$ valkey-cli -c -h 10.77.77.11 --user app --pass 'S3nhaApp!' --no-auth-warning set outro:x 1
NOPERM No permissions to access a key
$ valkey-cli -c -h 10.77.77.11 --user app --pass 'S3nhaApp!' --no-auth-warning flushall
NOPERM User app has no permissions to run the 'flushall' command
TLS em clientes, replicação e barramento
A imagem oficial e o binário oficial já vêm com TLS. Testamos um cluster separado de 3 nós só com TLS, usando uma CA própria e um certificado com os IPs no SAN:
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -subj "/CN=Valkey CA" -out ca.crt
openssl genrsa -out valkey.key 2048
openssl req -new -key valkey.key -subj "/CN=valkey-cluster" -out valkey.csr
printf "subjectAltName=IP:10.77.77.21,IP:10.77.77.22,IP:10.77.77.23\nextendedKeyUsage=serverAuth,clientAuth\n" > ext.cnf
openssl x509 -req -in valkey.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 825 -sha256 -extfile ext.cnf -out valkey.crt
# valkey.conf (trecho TLS)
port 0 # desliga a porta sem TLS
tls-port 6379
tls-cert-file /tls/valkey.crt
tls-key-file /tls/valkey.key
tls-ca-cert-file /tls/ca.crt
tls-cluster yes # barramento do cluster com TLS
tls-replication yes # replicação com TLS
tls-auth-clients yes # exige certificado do cliente (mTLS)
T="--tls --cacert /tls/ca.crt --cert /tls/valkey.crt --key /tls/valkey.key"
valkey-cli $T --cluster create 10.77.77.21:6379 10.77.77.22:6379 10.77.77.23:6379 --cluster-yes
valkey-cli $T -c -h 10.77.77.21 set tls:ok sim # OK
valkey-cli $T -c -h 10.77.77.22 get tls:ok # "sim"
valkey-cli -h 10.77.77.21 ping # Error: Connection reset by peer
valkey-cli --tls --cacert /tls/ca.crt -h 10.77.77.21 ping # Error: Server closed the connection
A primeira falha é um cliente sem TLS falando com a porta TLS. A segunda é um cliente com TLS mas sem certificado próprio, recusado pelo tls-auth-clients yes. Em produção, gere um certificado por nó. Para mais contexto sobre certificados, veja SSL/TLS no Postfix e no Dovecot.
Em servidores reais: binário oficial e systemd
Opções de instalação no Ubuntu e no Debian em setembro de 2026:
- Binário oficial em valkey.io/download: tarballs para Ubuntu 22.04 (jammy) e 24.04 (noble), em x86_64 e arm64, com a versão mais recente (9.1.2). É o que usamos abaixo.
- Pacote da distribuição: o Ubuntu 26.04 LTS traz o 9.0.4 (
apt install valkey-server valkey-tools, testado), o Debian 13 traz o 8.1.1 e o Ubuntu 24.04 ainda está no 7.2.x. Os pacotes já incluem as unitsvalkey-server.serviceevalkey-server@.service.
Nos seis servidores (aqui 10.0.0.11 a 10.0.0.16), ajuste o kernel como a documentação de administração recomenda:
echo 'vm.overcommit_memory = 1' | sudo tee /etc/sysctl.d/90-valkey.conf
sudo sysctl --system
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled # persista via unit ou GRUB
Instale o binário conferindo o SHA-256 e crie usuário, diretórios e configuração:
VER=9.1.2
cd /tmp
curl -fsSLO https://download.valkey.io/releases/valkey-${VER}-noble-x86_64.tar.gz
curl -fsSLO https://download.valkey.io/releases/valkey-${VER}-noble-x86_64.tar.gz.sha256
sha256sum -c valkey-${VER}-noble-x86_64.tar.gz.sha256 # ...tar.gz: OK
tar xzf valkey-${VER}-noble-x86_64.tar.gz
sudo install -m 755 valkey-${VER}-noble-x86_64/bin/* /usr/local/bin/
sudo useradd --system --home-dir /var/lib/valkey --shell /usr/sbin/nologin valkey
sudo install -d -o valkey -g valkey -m 750 /var/lib/valkey /var/log/valkey
sudo install -d -o root -g valkey -m 750 /etc/valkey
# /etc/valkey/valkey.conf (troque o IP do bind em cada servidor)
bind 10.0.0.11 127.0.0.1
port 6379
protected-mode yes
daemonize no
supervised systemd
dir /var/lib/valkey
logfile /var/log/valkey/valkey.log
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
appendonly yes
appendfsync everysec
save 3600 1 300 100
requirepass Troque-Esta-Senha
primaryauth Troque-Esta-Senha
maxmemory 2gb
maxmemory-policy noeviction
sudo chown root:valkey /etc/valkey/valkey.conf
sudo chmod 640 /etc/valkey/valkey.conf
Em cluster, maxmemory-policy noeviction faz o nó recusar escritas quando a memória acaba, em vez de apagar dados. Para uso só como cache, troque por allkeys-lru. A unit do systemd usa Type=notify, porque o binário oficial é compilado com suporte a systemd e avisa quando está pronto. Para os comandos de dia a dia do systemd, veja Dominando o systemd.
# /etc/systemd/system/valkey.service
[Unit]
Description=Valkey (cluster node)
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
User=valkey
Group=valkey
ExecStart=/usr/local/bin/valkey-server /etc/valkey/valkey.conf
Restart=on-failure
LimitNOFILE=65535
TimeoutStartSec=60
TimeoutStopSec=60
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lib/valkey /var/log/valkey /etc/valkey
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now valkey
systemctl status valkey # Active: active (running) ... Status: "Ready to accept connections"
Não é preciso ExecStop. O systemd manda SIGTERM, e o Valkey faz o fsync do AOF, grava o RDB final e salva o nodes.conf antes de sair. No teste, o log registrou “Saving the final RDB snapshot before exiting” e “Valkey is now ready to exit”. O /etc/valkey entra em ReadWritePaths para o caso de você usar CONFIG REWRITE. Libere as portas só para a rede dos nós e dos clientes:
sudo ufw allow from 10.0.0.0/24 to any port 6379,16379 proto tcp
Por fim, de qualquer um dos servidores:
valkey-cli -a 'Troque-Esta-Senha' --no-auth-warning --cluster create \
10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 \
10.0.0.14:6379 10.0.0.15:6379 10.0.0.16:6379 --cluster-replicas 1
Replicar isso em seis máquinas é trabalho para automação. O guia de Ansible cobre o básico para transformar os passos acima num playbook.
Valkey Admin: o cluster numa tela
O Valkey Admin é a ferramenta oficial de observação e gerenciamento do projeto, com licença Apache 2.0. A versão 1.0 saiu em maio de 2026 e a atual é a 1.1.1 (14/08/2026). Ele roda como aplicativo desktop para Linux (.deb e AppImage) e macOS, ou como aplicação web em Docker/Kubernetes. Entre os recursos estão dashboard de memória, CPU, clientes e hit ratio, navegador de chaves, envio de comandos com autocompletar, mapa de topologia do cluster, hot keys, big keys (novidade da 1.1) e o COMMANDLOG agregado de todos os nós.
No laboratório rodamos a versão web na mesma rede do cluster, publicada só no localhost:
docker run -d --name valkey-admin --network valkey-net --ip 10.77.77.60 \
-p 127.0.0.1:18080:8080 \
-e DEPLOYMENT_MODE=Web \
-e VALKEY_HOST=10.77.77.11 -e VALKEY_PORT=6379 \
-e VALKEY_AUTH_TYPE=password -e VALKEY_USERNAME=default \
-e 'VALKEY_PASSWORD=SenhaForte' \
valkey/valkey-admin:1.1.1
docker logs valkey-admin
# Server running at http://localhost:8080
# Starting metrics server for: 10-77-77-11-6379
# Starting metrics server for: 10-77-77-12-6379
# Starting metrics server for: 10-77-77-13-6379
# Cluster nodes and metrics servers are in sync
As variáveis VALKEY_* iniciam a coleta de métricas (um coletor por primário), mas a interface começa vazia. Abra http://127.0.0.1:18080, clique em + Add Connection e escolha Discovery para cluster. Preencha host, porta, usuário e senha. Atenção: no nosso teste, a opção Use TLS veio marcada por padrão no modo Discovery, e a conexão ficou parada em Connecting… até desmarcarmos a opção, já que o cluster do laboratório não usa TLS. Conectado, o Cluster Topology mostrou os 6 nós com os pares primário/réplica corretos:

Leia as limitações antes de pôr em produção:
- Não tem login próprio nem RBAC. Quem acessa a interface roda qualquer comando que a ACL do usuário configurado permitir. Coloque-o atrás de um proxy com autenticação (nginx, oauth2-proxy) e conecte com um usuário ACL restrito.
- Não suporta mTLS. Só TLS com senha. O cluster TLS com
tls-auth-clients yesque montamos acima não é compatível. - As métricas vêm só dos primários, e o navegador de chaves amostra cerca de 1.000 chaves (a busca usa
SCAN MATCH).
Monitoramento
O Valkey Admin é bom para investigar problemas, mas alerta é trabalho do Prometheus. O blog do Valkey tem um guia de exporters que usa o redis_exporter, compatível com o Valkey. Os alertas mínimos são cluster_state diferente de ok, master_link_status:down nas réplicas, memória perto do maxmemory e shard sem réplica. Se o Prometheus ainda não está no ar, comece por Monitorando Servidores Linux com Prometheus. Para um check externo simples de TCP na 6379 de cada nó, o Go Uptime resolve.
Troubleshooting: erros que apareceram no laboratório
CLUSTERDOWN Hash slot not served: o nó está em modo cluster, mas nenhum nó é dono do slot. Acontece antes do--cluster createou quando slots ficaram sem dono. Rodevalkey-cli --cluster checke, se for o caso,--cluster fix.CLUSTERDOWN The cluster is down: apareceu por um instante logo depois do--cluster createno cluster TLS, enquanto os nós convergiam. Dois segundos depois estavaok. Também aparece quando um shard perde o primário e a réplica. Derrubamos os nós 3 e 4 juntos, ecluster_slots_okcaiu para 10923. Comcluster-require-full-coverage no, os shards saudáveis continuam atendendo e só as chaves do shard morto falham.MOVED 7319 10.77.77.12:6379: cliente sem modo cluster. Usevalkey-cli -cou uma biblioteca com suporte a cluster. Se o redirecionamento aponta para um IP inalcançável, o problema é NAT oucluster-announce-iperrado.ASK 3844 10.77.77.12:6379: reproduzido marcando o slot comoMIGRATING/IMPORTINGà mão, no meio de uma migração chave a chave. O cliente com-csegue sozinho. Se um slot ficar preso nesse estado, o--cluster checkacusa open slots, e oCLUSTER SETSLOT <slot> STABLEou o--cluster fixresolvem.CROSSSLOT Keys in request don't hash to the same slot: comando multi-chave com chaves em slots diferentes. Use hash tags ({pedido:42}:...).master_link_status:downcomNOAUTHno log da réplica: faltaprimaryauthno nó.DENIED Running in protected mode: conexão remota sem senha no usuário default.Unrecognized option or bad number of args for: '-@dangerous': ovalkey-cli --cluster callinterpreta argumentos que começam com-como opções da própria ferramenta. Crie ACLs com um laço por nó, como mostrado acima.- O
AUTH failednão interrompe ovalkey-cli. Esse foi o susto do laboratório. Rodamos comandos com--user appantes de o usuário existir. Ovalkey-climostrouAUTH failed: WRONGPASSe continuou executando os comandos como usuáriodefault, que naquele momento não tinha senha. UmFLUSHALLde teste passou e apagou o shard 1 inteiro (cmdstat_flushall:calls=1noINFO commandstats). Mais um motivo para nunca deixar o usuáriodefaultsem senha.
Limpando o laboratório
docker rm -f valkey-{1..8} valkey-client valkey-admin 2>/dev/null
docker network rm valkey-net
Conclusão
O Valkey herdou o cluster do Redis e vem melhorando exatamente a parte que mais dava trabalho: o resharding virou atômico, o cluster aceita bancos numerados e a versão 9.1 trouxe ACL por banco e TLS com rotação de certificados. No teste, o failover levou cerca de 6 s com o cluster-node-timeout padrão do tutorial e cerca de 3 s com 2000 ms, sem intervenção. Esse número é o que você deve levar à conversa com o time da aplicação, junto com a exigência de um cliente que entenda cluster. Se o seu problema é alta disponibilidade de banco relacional, veja o cluster MariaDB Galera com mariabackup. Se o cluster vai rodar em Kubernetes bare metal, o MetalLB resolve a exposição dos serviços.