Category: infraestrutura

Woman in the office

Configuração do Redis Cluster (modo cluster habilitado) com failover automático

Redis é um armazenamento de dados em memória de código aberto usado como banco de dados ou cache. Ele possui replicação integrada e oferece alta disponibilidade por meio do Redis Sentinel e particionamento automático com Redis Cluster. Neste artigo, veremos o que é e como instalar um Redis Cluster.

 

O que é o Redis Cluster?

O Redis Cluster é um recurso integrado do Redis que oferece fragmentação automática, replicação e alta disponibilidade, que foi implementado anteriormente com o Sentinels. Ele tem a capacidade de dividir automaticamente seu conjunto de dados entre vários nós e continuar as operações quando um subconjunto de nós está passando por falhas ou não consegue se comunicar com o resto do cluster.

 

Como instalar o Redis Cluster 

De acordo com a documentação oficial, o cluster mínimo que funciona conforme o esperado precisa conter pelo menos três nós master, mas na verdade, a recomendação é ter um cluster de seis nós com três masters e três nós para os slaves, então vamos configurar isso. 

Para este exemplo, instalaremos o Redis Cluster no CentOS 8, ou similares (OEL 8, RedHat 8, AlmaLinux 8, etc) usando a seguinte topologia: 

 

Master 1: 192.168.203.11
Master 2: 192.168.203.12
Master 3: 192.168.203.13
Slave 1: 192.168.203.14
Slave 2: 192.168.203.15
Slave 3: 192.168.203.16

 

Os seguintes comandos devem ser executados em todos os nós, mestre e escravo. Por padrão, durante a criação desta postagem do blog, a versão Redis disponível no CentOS 8 é 5.0.3, então vamos usar o Repositório Remi para ter a versão estável 6.2 atual:
$ dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm -y
$ dnf module install redis:remi-6.2 -y
$ systemctl enable redis.service

 

Para configurar seu Cluster Redis, você precisa editar o arquivo de configuração do Redis /etc/redis.conf e alterar os seguintes parâmetros:
$ vim /etc/redis.conf
bind 192.168.203.11 #Substitua este endereço IP pelo endereço IP local em cada nó
protected-mode no
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
appendonly yes

 

Esses parâmetros são:

  • bind: Por padrão, se não for especificado, o Redis escuta as conexões de todas as interfaces de rede disponíveis no servidor. É possível ouvir apenas uma ou várias interfaces selecionadas. 
  • protected-mode: o modo protegido é uma camada de proteção de segurança, a fim de evitar que instâncias do Redis deixadas abertas na internet sejam acessadas e exploradas. Por padrão, o modo protegido está habilitado.
  • port: Aceita conexões na porta especificada, o padrão é 6379. Se a porta 0 for especificada, o Redis não escutará em um soquete TCP. 
  • cluster-enabled: Habilita / desabilita o suporte ao Redis Cluster em um nó específico do Redis. Se estiver desativado, a instância começa como uma instância autônoma, como de costume.
  • cluster-config-file: O arquivo em que um nó do Redis Cluster persiste automaticamente a configuração do cluster sempre que houver uma alteração, para poder relê-lo na inicialização.
  • cluster-node-timeout: o tempo máximo (em milissegundos) que um nó do Redis Cluster pode ficar indisponível, sem que seja considerado uma falha. Se um nó mestre não for alcançável por mais do que o período de tempo especificado, ele sofrerá failover por seus escravos.
  • appendonly: O arquivo Append Only é um modo de persistência alternativo que oferece durabilidade muito melhor. Para instâncias que usam a política de fsync de dados padrão, o Redis pode perder apenas um segundo de gravações em uma falha do servidor, como queda de energia, ou uma única gravação se algo estiver errado com o próprio processo do Redis, mas o sistema operacional ainda estiver funcionando corretamente.

 Cada nó do Redis Cluster requer duas conexões TCP abertas. A porta Redis TCP normal usada para atender clientes, por padrão 6379, e a porta obtida adicionando 10000 à porta de dados, portanto, por padrão 16379. Esta segunda porta é atribuída ao barramento de cluster, que é usado por nós para detecção de falhas, atualização de configuração, autorização de failover e muito mais.

Agora você pode iniciar o serviço Redis:
$ systemctl start redis.service
No arquivo de log do Redis, por padrão /var/log/redis/redis.log, você verá o seguinte:
$ 76:M 15 Jul 2021 15:10:18.658 * Ready to accept connections
Agora que tudo está pronto, você precisa criar o cluster usando a ferramenta redis-cli. Para isso, você deve executar o seguinte comando em apenas um nó:
$ redis-cli --cluster create 192.168.203.11:7000 192.168.203.12:7000 192.168.203.13:7000 192.168.203.14:7000 192.168.203.15:7000 192.168.203.16:7000 --cluster-replicas 1
Neste comando, você precisa adicionar o endereço IP e a porta Redis para cada nó. Os três primeiros nós serão os nós mestres e os demais os escravos. O cluster-replicas 1 significa um nó escravo para cada mestre. A saída desse comando será semelhante a esta:
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.203.15:7000 to 192.168.203.11:7000
Adding replica 192.168.203.16:7000 to 192.168.203.12:7000
Adding replica 192.168.203.14:7000 to 192.168.203.13:7000
M: 4394d8eb03de1f524b56cb385f0eb9052ce65283 192.168.203.11:7000
 slots:[0-5460] (5461 slots) master
M: 5cc0f693985913c553c6901e102ea3cb8d6678bd 192.168.203.12:7000
  slots:[5461-10922] (5462 slots) master
M: 22de56650b3714c1c42fc0d120f80c66c24d8795 192.168.203.13:7000
  slots:[10923-16383] (5461 slots) master
S: 8675cd30fdd4efa088634e50fbd5c0675238a35e 192.168.203.14:7000
  replicates 22de56650b3714c1c42fc0d120f80c66c24d8795
S: ad0f5210dda1736a1b5467cd6e797f011a192097 192.168.203.15:7000
  replicates 4394d8eb03de1f524b56cb385f0eb9052ce65283
S: 184ada329264e994781412f3986c425a248f386e 192.168.203.16:7000
  replicates 5cc0f693985913c553c6901e102ea3cb8d6678bd
Can I set the above configuration? (type 'yes' to accept):
Após aceitar a configuração, o cluster será criado:

>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.203.11:7000)
M: 4394d8eb03de1f524b56cb385f0eb9052ce65283 192.168.203.11:7000
  slots:[0-5460] (5461 slots) master
  1 additional replica(s)
S: 184ada329264e994781412f3986c425a248f386e 192.168.203.16:7000
  slots: (0 slots) slave
  replicates 5cc0f693985913c553c6901e102ea3cb8d6678bd
M: 5cc0f693985913c553c6901e102ea3cb8d6678bd 192.168.203.12:7000
  slots:[5461-10922] (5462 slots) master
  1 additional replica(s)
M: 22de56650b3714c1c42fc0d120f80c66c24d8795 192.168.203.13:7000
  slots:[10923-16383] (5461 slots) master
  1 additional replica(s)
S: ad0f5210dda1736a1b5467cd6e797f011a192097 192.168.203.15:7000
  slots: (0 slots) slave
  replicates 4394d8eb03de1f524b56cb385f0eb9052ce65283
S: 8675cd30fdd4efa088634e50fbd5c0675238a35e 192.168.203.14:7000
  slots: (0 slots) slave
  replicates 22de56650b3714c1c42fc0d120f80c66c24d8795
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Se você der uma olhada no arquivo de log mestre, verá:

3543:M 15 Jul 2021 15:20:23.250 # configEpoch set to 1 via CLUSTER SET-CONFIG-EPOCH
3543:M 15 Jul 2021 15:20:23.258 # IP address for this node updated to 192.168.203.11
3543:M 15 Jul 2021 15:20:25.281 * Replica 192.168.203.15:7000 asks for synchronization
3543:M 15 Jul 2021 15:20:25.281 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for '1f42a85e22d8a19817844aeac14fbb8201a6fc88', my replication
IDs are '9f8db08a36207c17800f75487b193a624f17f091' and '0000000000000000000000000000000000000000')
3543:M 15 Jul 2021 15:20:25.281 * Replication backlog created, my new replication IDs are '21abfca3b9405356569b2684c6d68c0d2ec19b3b' and '0000000000000000000000000000000000000000'
3543:M 15 Jul 2021 15:20:25.281 * Starting BGSAVE for SYNC with target: disk
3543:M 15 Jul 2021 15:20:25.284 * Background saving started by pid 3289
3289:C 15 Jul 2021 15:20:25.312 * DB saved on disk
3289:C 15 Jul 2021 15:20:25.313 * RDB: 0 MB of memory used by copy-on-write
3543:M 15 Jul 2021 15:20:25.369 * Background saving terminated with success
3543:M 15 Jul 2021 15:20:25.369 * Synchronization with replica 192.168.203.15:7000 succeeded
3543:M 15 Jul 2021 15:20:28.180 # Cluster state changed: ok

E o arquivo de log da réplica:

11531:M 15 Jul 2021 15:20:23.253 # configEpoch set to 4 via CLUSTER SET-CONFIG-EPOCH
11531:M 15 Jul 2021 15:20:23.357 # IP address for this node updated to 192.168.203.14
11531:S 15 Jul 2021 15:20:25.277 * Before turning into a replica, using my own master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
11531:S 15 Jul 2021 15:20:25.277 * Connecting to MASTER 192.168.203.13:7000
11531:S 15 Jul 2021 15:20:25.277 * MASTER <-> REPLICA sync started
11531:S 15 Jul 2021 15:20:25.277 # Cluster state changed: ok
11531:S 15 Jul 2021 15:20:25.277 * Non blocking connect for SYNC fired the event.
11531:S 15 Jul 2021 15:20:25.278 * Master replied to PING, replication can continue...
11531:S 15 Jul 2021 15:20:25.278 * Trying a partial resynchronization (request 7d8da986c7e699fe33002d10415f98e91203de01:1).
11531:S 15 Jul 2021 15:20:25.279 * Full resync from master: 99a8defc35b459b7b73277933aa526d3f72ae76e:0
11531:S 15 Jul 2021 15:20:25.279 * Discarding previously cached master state.
11531:S 15 Jul 2021 15:20:25.299 * MASTER <-> REPLICA sync: receiving 175 bytes from master to disk
11531:S 15 Jul 2021 15:20:25.299 * MASTER <-> REPLICA sync: Flushing old data
11531:S 15 Jul 2021 15:20:25.300 * MASTER <-> REPLICA sync: Loading DB in memory
11531:S 15 Jul 2021 15:20:25.306 * Loading RDB produced by version 6.2.4
11531:S 15 Jul 2021 15:20:25.306 * RDB age 0 seconds
11531:S 15 Jul 2021 15:20:25.306 * RDB memory usage when created 2.60 Mb
11531:S 15 Jul 2021 15:20:25.306 * MASTER <-> REPLICA sync: Finished with success
11531:S 15 Jul 2021 15:20:25.308 * Background append only file rewriting started by pid 2487
11531:S 15 Jul 2021 15:20:25.342 * AOF rewrite child asks to stop sending diffs.
2487:C 15 Jul 2021 15:20:25.342 * Parent agreed to stop sending diffs. Finalizing AOF...
2487:C 15 Jul 2021 15:20:25.342 * Concatenating 0.00 MB of AOF diff received from parent.
2487:C 15 Jul 2021 15:20:25.343 * SYNC append only file rewrite performed
2487:C 15 Jul 2021 15:20:25.343 * AOF rewrite: 0 MB of memory used by copy-on-write
11531:S 15 Jul 2021 15:20:25.411 * Background AOF rewrite terminated with success
11531:S 15 Jul 2021 15:20:25.411 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
11531:S 15 Jul 2021 15:20:25.411 * Background AOF rewrite finished successfully

 

Monitorando nós de cluster do Redis 

Para saber o status de cada nó do Redis, você pode usar o seguinte comando:
$ redis-cli -h 192.168.203.11 -p 7000 cluster nodes
184ada329264e994781412f3986c425a248f386e 192.168.203.16:[email protected] slave 5cc0f693985913c553c6901e102ea3cb8d6678bd 0 1625255155519 2 connected
5cc0f693985913c553c6901e102ea3cb8d6678bd 192.168.203.12:[email protected] master - 0 1625255153513 2 connected 5461-10922
22de56650b3714c1c42fc0d120f80c66c24d8795 192.168.203.13:[email protected] master - 0 1625255151000 3 connected 10923-16383
ad0f5210dda1736a1b5467cd6e797f011a192097 192.168.203.15:[email protected] slave 4394d8eb03de1f524b56cb385f0eb9052ce65283 0 1625255153000 connected
8675cd30fdd4efa088634e50fbd5c0675238a35e 192.168.203.14:[email protected] slave 22de56650b3714c1c42fc0d120f80c66c24d8795 0 1625255154515 connected
4394d8eb03de1f524b56cb385f0eb9052ce65283 192.168.203.11:[email protected] myself,master - 0 1625255152000 1 connected 0-5460

Você também pode filtrar a saída usando o comando grep linux para verificar apenas os nós mestres:
$ redis-cli -h 192.168.203.11 -p 7000 cluster nodes  | grep master
5cc0f693985913c553c6901e102ea3cb8d6678bd 192.168.203.12:[email protected] master - 0 1625255389768 2 connected 5461-10922
22de56650b3714c1c42fc0d120f80c66c24d8795 192.168.203.13:[email protected] master - 0 1625255387000 3 connected 10923-16383
4394d8eb03de1f524b56cb385f0eb9052ce65283 192.168.203.11:[email protected] myself,master - 0 1625255387000 1 connected 0-5460

Ou mesmo os nós slaves:
$ redis-cli -h 192.168.203.11 -p 7000 cluster nodes  | grep slave
184ada329264e994781412f3986c425a248f386e 192.168.203.16:[email protected] slave 5cc0f693985913c553c6901e102ea3cb8d6678bd 0 1625255395795 2 connected
ad0f5210dda1736a1b5467cd6e797f011a192097 192.168.203.15:[email protected] slave 4394d8eb03de1f524b56cb385f0eb9052ce65283 0 1625255395000 1 connected
8675cd30fdd4efa088634e50fbd5c0675238a35e 192.168.203.14:[email protected] slave 22de56650b3714c1c42fc0d120f80c66c24d8795 0 1625255393000 3 connected

 

Failover automático do Redis Cluster

Vamos testar o recurso de failover automático no Redis Cluster. Para isso, vamos interromper o serviço Redis em um nó mestre e ver o que acontece.
No Master 2 – 192.168.203.12:
$ systemctl stop redis
$ systemctl status redis |grep Active
   Active: inactive (dead) since Fri 2021-07-15 15:25:41 UTC; 1h 4min ago

Agora, vamos verificar a saída do comando que usamos na seção anterior para monitorar os nós do Redis:

$ redis-cli -h 192.168.203.11 -p 7000 cluster nodes
184ada329264e994781412f3986c425a248f386e 192.168.203.16:[email protected] master - 0 1625255654350 7 connected 5461-10922
5cc0f693985913c553c6901e102ea3cb8d6678bd 192.168.203.12:[email protected] master,fail - 1625255622147 1625255621143 2 disconnected
22de56650b3714c1c42fc0d120f80c66c24d8795 192.168.203.13:[email protected] master - 0 1625255654000 3 connected 10923-16383
ad0f5210dda1736a1b5467cd6e797f011a192097 192.168.203.15:[email protected] slave 4394d8eb03de1f524b56cb385f0eb9052ce65283 0 1625255656366 1 connected 8675cd30fdd4efa088634e50fbd5c0675238a35e 192.168.203.14:[email protected] slave 22de56650b3714c1c42fc0d120f80c66c24d8795 0 1625255655360 3 connected
4394d8eb03de1f524b56cb385f0eb9052ce65283 192.168.203.11:[email protected] myself,master - 0 1625255653000 1 connected 0-5460

Como você pode ver, um dos nós slaves foi promovido a master, neste caso, Slave 3 – 192.168.203.16, de modo que o failover automático funcionou conforme o esperado.

 

Conclusão

Redis é uma boa opção caso você queira usar um armazenamento de dados na memória. Como você pode ver neste artigo, a instalação não é uma ciência espacial e o uso do Redis Cluster é explicado em sua documentação oficial. Este blog cobre apenas as etapas básicas de instalação e teste, mas você também pode melhorar isso, por exemplo, adicionando autenticação na configuração do Redis ou até mesmo executando um benchmark usando a ferramenta redis-benchmark para verificar o desempenho.

Learn More