Garantindo Alta Disponibilidade no Redis com Redis Sentinel
O Redis, como já conhecemos, é um banco de dados em memória responsável pelo caching. No entanto, por se tratar de um banco de dados, ele também oferece suporte à replicação e ao failover em casos extremos.
Neste post, vamos abordar como configurar o Redis Sentinel para garantir redundância e failover em um ambiente Redis.
Redis Sentinel
O Redis Sentinel é um utilitário que monitora e gerencia instâncias do Redis, determinando os papéis de master e slave em casos de failover, atuando, de certa forma, como um árbitro. Com um ou mais sentinelas, é possível formar um quórum, que decide as ações a serem tomadas durante um failover.
Instalação do Redis
O redis sentinel, já vem juntamente com a instalação do redis, então, para instalarmos, podemos seguir a propria documentação para ubuntu, debian e derivados: https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/
Ou fazer a instalação via repositório quando falamos de redhat, conforme é instruido pela documentação:
yum install redis
Para este post, estamos utilizando duas máquinas virtuais com Red Hat Linux 9.4 (Plow).
IPs das máquinas virtuais:
- Master: 172.27.11.10 (redhat-redis-01)
- Slave: 172.27.11.20 (redhat-redis-02)
O Redis foi instalado com o comando padrão do YUM e o serviço foi habilitado em ambas as máquinas virtuais:
yum install redis
systemctl enable --now redis
O parâmetro
enable
habilita o serviço para iniciar automaticamente no boot, enquanto--now
o inicia imediatamente.
Além disso, foi necessário liberar as portas do Redis (6379) e do Redis Sentinel (26379) no firewall do Linux:
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --permanent --add-port=26379/tcp
firewall-cmd --reload
Agora, vamos à configuração do Redis nos servidores master e slave.
Configuração no servidor master
No arquivo /etc/redis/redis.conf, adicione as seguintes configurações:
bind 0.0.0.0
port 6379
requirepass redis123
masterauth redis123
Configuração no servidor slave
No arquivo /etc/redis/redis.conf, adicione as seguintes configurações:
bind 0.0.0.0
port 6379
requirepass redis123
masterauth redis123
replicaof 172.27.11.10 6379
Os parâmetros adicionados foram:
- bind: permite que o Redis escute conexões de qualquer endereço na rede (0.0.0.0).
- port: define a porta padrão do Redis (6379).
- requirepass: define a senha padrão do Redis, criada para esta demonstração.
- masterauth: especifica a senha necessária para que um nó slave possa se conectar ao master, quando aplicável.
- replicaof (no slave): indica o IP e a porta do servidor master ao qual o nó slave se replicará. No caso desta configuração, o master está em 172.27.11.10:6379.
Depois de configurado, reinicie o serviço do Redis nos servidores master e slave para que as configurações sejam aplicadas:
systemctl restart redis
Agora, com o Redis funcional e a replicação ativa, vamos configurar o Redis Sentinel.
Antes de iniciar a configuração, em alguns casos, podem ocorrer erros de permissão durante a edição dos arquivos. Para evitar isso, pode ser necessário ajustar as permissões dos arquivos de configuração e log:
chown redis:redis /etc/redis/sentinel.conf
chown redis:redis /var/log/redis/sentinel.log
Agora vamos editar o arquivo /etc/redis/sentinel.conf no servidor master:
bind 172.27.11.10 127.0.0.1
sentinel monitor mymaster 172.27.11.10 6379 2
sentinel auth-pass mymaster redis123
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
Agora a configuração do servidor slave no mesmo arquivo:
bind 172.27.11.20 127.0.0.1
sentinel monitor mymaster 172.27.11.10 6379 2
sentinel auth-pass mymaster redis123
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
Os parâmetros adicionados foram:
- bind: define os endereços nos quais o Sentinel deve escutar conexões. Neste caso, ele escutará apenas no IP local do servidor e no localhost.
- sentinel monitor: especifica o nome do servidor master (definido como mymaster), junto com seu IP e porta. O número 2 define o quórum, ou seja, é necessário que 2 ou mais sentinelas contribuam para a atribuição do master.
- sentinel auth-pass mymaster: define a senha de autenticação para conexão com o servidor master que foi definida em requirepass no /etc/.
- sentinel down-after-milliseconds: determina o tempo (em milissegundos) que uma instância pode ficar inacessível antes de o Sentinel considerá-la inativa.
- sentinel failover-timeout: caso um Sentinel já tenha votado em outro Sentinel para realizar o failover de um determinado master, ele aguardará esse período (em milissegundos) antes de tentar um novo failover para o mesmo master.
Por fim, vamos habilitar e iniciar o serviço do Redis Sentinel nos servidores master e slave:
systemctl enable --now redis-sentinel
A partir desse momento, o failover já estará ativo. Por exemplo, se o serviço Redis for interrompido no servidor master:
[root@redhat-redis-01 redis]# systemctl stop redis
[root@redhat-redis-01 redis]#
O servidor secundário, monitorado pelo Sentinel, assumirá o papel de master, como pode ser observado no arquivo de log /var/log/redis/sentinel.log do servidor slave:
7457:X 02 Feb 2025 16:59:53.101 # +sdown master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:53.157 # +odown master mymaster 172.27.11.10 6379 #quorum 2/2
7457:X 02 Feb 2025 16:59:53.157 # +new-epoch 1
7457:X 02 Feb 2025 16:59:53.157 # +try-failover master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:53.170 # +vote-for-leader bb26e0e5c9b7f5c7735a608c6352c804eef425e3 1
7457:X 02 Feb 2025 16:59:53.194 # 79c624a256d5471cbcab7523ecbd02b97af3689d voted for bb26e0e5c9b7f5c7735a608c6352c804eef425e3 1
7457:X 02 Feb 2025 16:59:53.222 # +elected-leader master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:53.222 # +failover-state-select-slave master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:53.281 # +selected-slave slave 172.27.11.20:6379 172.27.11.20 6379 @ mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:53.281 * +failover-state-send-slaveof-noone slave 172.27.11.20:6379 172.27.11.20 6379 @ mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:53.353 * +failover-state-wait-promotion slave 172.27.11.20:6379 172.27.11.20 6379 @ mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:54.217 # +promoted-slave slave 172.27.11.20:6379 172.27.11.20 6379 @ mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:54.217 # +failover-state-reconf-slaves master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:54.293 # +failover-end master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:54.293 # +switch-master mymaster 172.27.11.10 6379 172.27.11.20 6379
7457:X 02 Feb 2025 16:59:54.294 * +slave slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7457:X 02 Feb 2025 16:59:59.307 # +sdown slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
No entanto, ao reiniciar o Redis no servidor master, ele retornará como secundário:
[root@redhat-redis-01 redis]# systemctl stop redis
[root@redhat-redis-01 redis]# systemctl start redis
[root@redhat-redis-01 redis]# tail /var/log/redis/sentinel.log
7245:X 02 Feb 2025 16:59:53.077 # +new-epoch 1
7245:X 02 Feb 2025 16:59:53.088 # +vote-for-leader bb26e0e5c9b7f5c7735a608c6352c804eef425e3 1
7245:X 02 Feb 2025 16:59:54.018 # +odown master mymaster 172.27.11.10 6379 #quorum 2/2
7245:X 02 Feb 2025 16:59:54.018 # Next failover delay: I will not start a failover before Sun Feb 2 17:01:53 2025
7245:X 02 Feb 2025 16:59:54.199 # +config-update-from sentinel bb26e0e5c9b7f5c7735a608c6352c804eef425e3 172.27.11.20 26379 @ mymaster 172.27.11.10 6379
7245:X 02 Feb 2025 16:59:54.199 # +switch-master mymaster 172.27.11.10 6379 172.27.11.20 6379
7245:X 02 Feb 2025 16:59:54.200 * +slave slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 16:59:59.276 # +sdown slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:01:23.415 # -sdown slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:01:33.387 * +convert-to-slave slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
[root@redhat-redis-01 redis]#
Com o slave atuando como master, como podemos realizar o fallback para que o servidor master reassuma seu papel original?
Simples! Basta declarar o failover a partir de um dos servidores Sentinel com o seguinte comando:
[root@redhat-redis-01 ~]# redis-cli -p 26379 sentinel failover mymaster
OK
[root@redhat-redis-01 ~]#
Assim, podemos verificar nos logs do servidor master que ele reassumiu o seu papel:
[root@redhat-redis-01 redis]# redis-cli -p 26379 sentinel failover mymaster
OK
[root@redhat-redis-01 redis]# tail /var/log/redis/sentinel.log
7245:X 02 Feb 2025 17:02:40.253 # +elected-leader master mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:40.253 # +failover-state-select-slave master mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:40.309 # +selected-slave slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:40.309 * +failover-state-send-slaveof-noone slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:40.411 * +failover-state-wait-promotion slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:41.319 # +promoted-slave slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:41.319 # +failover-state-reconf-slaves master mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:41.390 # +failover-end master mymaster 172.27.11.20 6379
7245:X 02 Feb 2025 17:02:41.390 # +switch-master mymaster 172.27.11.20 6379 172.27.11.10 6379
7245:X 02 Feb 2025 17:02:41.391 * +slave slave 172.27.11.20:6379 172.27.11.20 6379 @ mymaster 172.27.11.10 6379
[root@redhat-redis-01 redis]#
E o servidor slave foi reconvertido para secundário:
[root@redhat-redis-02 redis]# tail /var/log/redis/sentinel.log
7457:X 02 Feb 2025 16:59:54.217 # +failover-state-reconf-slaves master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:54.293 # +failover-end master mymaster 172.27.11.10 6379
7457:X 02 Feb 2025 16:59:54.293 # +switch-master mymaster 172.27.11.10 6379 172.27.11.20 6379
7457:X 02 Feb 2025 16:59:54.294 * +slave slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7457:X 02 Feb 2025 16:59:59.307 # +sdown slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7457:X 02 Feb 2025 17:01:24.006 # -sdown slave 172.27.11.10:6379 172.27.11.10 6379 @ mymaster 172.27.11.20 6379
7457:X 02 Feb 2025 17:02:40.528 # +new-epoch 2
7457:X 02 Feb 2025 17:02:41.508 # +config-update-from sentinel 79c624a256d5471cbcab7523ecbd02b97af3689d 172.27.11.10 26379 @ mymaster 172.27.11.20 6379
7457:X 02 Feb 2025 17:02:41.508 # +switch-master mymaster 172.27.11.20 6379 172.27.11.10 6379
7457:X 02 Feb 2025 17:02:41.509 * +slave slave 172.27.11.20:6379 172.27.11.20 6379 @ mymaster 172.27.11.10 6379
Conclusão
Com o Redis Sentinel, podemos concluir que ter uma ferramenta nativa de failover, com poucos passos de configuração, é de extrema importância no dia a dia, especialmente em ambientes escaláveis e de alta disponibilidade. Além disso, a configuração do Sentinel pode ser realizada com 2 ou mais nós Redis em replicação, garantindo a continuidade e a disponibilidade do Redis para as aplicações.