Concrete Logo
Hamburger button

Redis – Parte 2

  • Blog
  • 4 de Março de 2013
Share

Este é o segundo post da série sobre Redis, iniciada aqui no blog com o post Redis – Parte 1. Aqui, vamos abordar aspectos mais avançados como persistência e replicação de dados, como o Redis oferece suporte a tais aspectos e também abordar algumas estratégias de uso adequado em produção.

TIP: Assumo que você já possui o Redis corretamente instalado. Caso não tenha, veja aqui.

1 – Persistência

No primeiro post desta série, falamos que o Redis foi projetado para armazenar dados na memória RAM, sendo este um dos segredos por trás de sua incrível performance. No entanto, sabe-se que a memória RAM é altamente volátil e que não existem sistemas computacionais totalmente imunes a falhas. Quedas de energia, falhas de hardware ou a extinção do processo de SO, simplesmente, acontecem. Neste cenário, o que pode ser aceitável para uso como caching engine, certamente, não funciona para um data storage.

Como já dito no primeiro post da série, o Redis oferece suporte a persistência de seu dataset em disco, usando duas estratégias distintas:

Snapshotting

Nesta estratégia, também conhecida como RDB, a persistência do dataset no disco respeita dois critérios combinados: Tempo decorrido (em segundos) e Quantidade de alterações realizadas no dataset, a partir do último backup realizado. Isto significa que o Redis realizará o backup SE e SOMENTE SE ambos os critérios forem atendidos. Tais critérios são estabelecidos e configurados como savepoints, utilizando a parâmetro de configuração save, ao iniciar o Redis em linha de comando, por parametrização inline ou por arquivo .conf.

Por exemplo, podemos instruir a instância do Redis para realizar o backup a cada 3 segundos e 3 atualizações do dataset. Quando os critérios forem atingidos, o Redis vai fazer um fork() e iniciará o backup, enquanto a instância continua operando sem bloqueios de I/O. Para começar, inicie uma instância do Redis conforme abaixo:

[sourcecode language=”bash”]
~$ redis-server –port 9999 –daemonize yes –save 3 3
[/sourcecode]

Aqui, iniciamos o Redis na porta 9999, em modo daemon e configurado para criar um arquivo de backup chamado “dump.rdb”, na pasta onde executamos o binário (eu executei na minha pasta $HOME). Agora experimente:

[sourcecode language=”bash”]
~$ redis-cli -p 9999 SET teste1 123
~$ redis-cli -p 9999 SET teste2 123
~$ redis-cli -p 9999 SET teste3 123
[/sourcecode]

Aguarde 3 segundos e consulte a pasta $HOME:

[sourcecode language=”bash”]
-rw-rw-r– 1 usuario grupo 50 Feb 22 00:00 dump.rdb
[/sourcecode]

Pronto. Seu dataset está persistido e pronto para ser usado em casos de recuperação. Por padrão, o Redis salva o arquivo na mesma pasta onde o processo foi executado. Para personalizar, basta informar a diretiva dir PATH/ONDE/SALVAR na inicialização da instância ou definir a mesma no arquivo .conf utilizado para inicializar a instância. Também é possível personalizar o nome do arquivo, com a diretiva dbfilename NOME.rdb.

Log appending

Neste cenário, conhecido como AOF (Append only file), o Redis irá persistir toda e qualquer alteração do dataset em um arquivo temporário, sendo este gravado em disco de acordo com a política de fsync configurada. Por padrão, o arquivo é salvo em disco a cada 1 segundo. A vantagem desta estratégia, em relação ao RDB, são backups mais duráveis e com menor possibilidade de perda de dados por conta de desastres, como quedas de energia. Como desvantagem, o processo de backup pode ser ligeiramente mais lento e o tamanho do arquivo ser um pouco maior.

Para iniciar uma instância no modo AOF, basta executar:

[sourcecode language=”bash”]
~$ redis-server –port 9998 –daemonize yes –save “” –appendonly yes
[/sourcecode]

Repita os comandos de inserção de dados e verifique seu filesystem

[sourcecode language=”bash”]
-rw-rw-r– 1 usuario grupo 50 Feb 22 00:00 appendonly.aof
[/sourcecode]

Lembrando que, independente da estratégia, o Redis fará a restauração do backup durante a inicialização da instância, sempre que encontrar o dump correspondente aos parâmetros dbfilename e/ou appendfilename.

Já sabemos como configurar o Redis para persistir o dataset, certo? Mas há algo muito importante que cabe perguntar aqui:

De nada adianta guardar os dumps no próprio servidor, se o disco falhar. O que fazer?

Poderíamos pensar e implementar N maneiras diferentes de guardar os backups gerados pelo Redis, em locais seguros. Entretanto, uma das maneiras mais simples e eficazes que já implementei é utilizar o serviço Amazon S3 para armazenamento na nuvem, em conjunto com a ferramenta de linha de comando s3cmd.

Utilizando estas ferramentas, podemos implementar um modelo automatizado para exportar, periodicamente, o dump gerado para o S3.

TIP: Se você ainda não tem registro na Amazon Web Services, clique aqui e utilize os níveis de uso gratuito.

Comece por instalar o s3cmd, conforme abaixo:

[sourcecode language=”bash”]
~$ sudo apt-get install s3cmd gnupg
[/sourcecode]

Se tudo foi instalado corretamente, vamos configurar o s3cmd com o comando:

[sourcecode language=”bash”]
~$ s3cmd –configure
[/sourcecode]

Algumas perguntas serão feitas, como fornecer a chave de acesso e a chave secreta da AWS, uma senha para criptografia dos arquivos que serão armazenados no S3, dentre outras. Prossiga utilizando as respostas sugeridas, até encerrar a configuração.

Tudo certo? Agora podemos criar buckets, o que equivalem a diretórios no seu filesystem, e enviar os dumps do Redis diretamente para a sua área no S3, devidamente criptografados. Execute os comandos abaixo e acompanhe o resultado:

TIP: Os buckets devem ser únicos em toda a rede do S3. O nome “backup-redis-teste-blog-concrete” é uma sugestão. Troque por outro valor.

[sourcecode language=”bash”]
~$ s3cmd mb s3://backup-redis-teste-blog-concrete
~$ s3cmd put appendonly.aof s3://backup-redis-teste-blog-concrete/appendonly.aof
./appendonly.aof -> s3://backup-redis-teste-blog-concrete/appendonly.aof [1 of 1]
57 of 57 100% in 0s 116.05 B/s done
[/sourcecode]

Caso seja necessário restaurar um backup, basta recuperar o dump correspondente utilizando o comando GET. O s3cmd fará o download e a descriptografia automática. Execute:

[sourcecode language=”bash”]
~$ s3cmd get s3://backup-redis-teste-blog-concrete/appendonly.aof appendonly.aof
[/sourcecode]

Para automatizar o processo de backup, você pode combinar os comandos do s3cmd em um shell script, para execução automática e recorrente via Cron ou qualquer outro scheduler. A partir daí, seus dados estarão mais seguros e sua infra-estrutura mais preparada para o pior.

Para conferir o detalhamento completo sobre persistência no Redis, clique aqui.

2 – Replicação

Uma das funcionalidades que fazem do Redis uma ferramenta super versátil é, sem dúvida, a replicação. É possível configurar duas ou mais instâncias do Redis para sincronizar o estado do dataset entre si, em um modelo master/slave, onde o processo master envia ao processo slave toda e qualquer alteração efetuada no dataset.

Redis replication model

Legal. Mas para quê eu precisaria de duas ou mais instâncias, com os mesmos dados?

Usando replicação, você pode implementar duas estratégias muito úteis em ambientes de produção:

  • Alta disponibilidade: Imagine que o servidor que executa sua instância master do Redis está pouco responsivo ou falhando. Você precisa diagnosticar e resolver o problema, se possível, antes que os clientes da instância parem de operar. Como agir, sem impôr um mínimo de downtime aos clientes?

    Você pode ter duas instâncias do Redis configuradas como master/slave e, executando alguma estratégia de failover, redirecionar os clientes para conexão ao processo slave, que passaria a operar como um novo processo master, dando a você a chance de desligar o antigo master para diagnóstico, mantendo os clientes conectados, com downtime próximo a zero.

    redis_failover

    O time de desenvolvimento do Redis está trabalhando em um sub-projeto chamado Sentinel, que tem como uma de suas funções a implementação de mecanismos de failover. O projeto está em estágio beta. Também existem outros projetos com essa função, como o redis_failover, para uso em projetos Ruby.

  • Escalabilidade: O modelo de replicação do Redis permite a configuração de várias instâncias slave para um determinado processo master. É possível conectar instâncias slave em outras instâncias slave, formando um grafo.Redis replication modelAgora imagine que você precisa, por exemplo, transmitir os eventos das partidas de futebol da próxima Copa do Mundo, com altos índices de audiência e picos de milhares de acessos simultâneos, em um grande portal da Internet. Milhares de pessoas ao redor do mundo, acessando seu site, querendo saber o que acontece nos jogos.Utilizando o Redis, em conjunto com uma solução de balanceamento de carga, como por exemplo o Amazon Elastic Load Balancing, é possível distribuir a demanda sobre as várias instâncias slave, enquanto o processo master recebe as atualizações e coordena a replicação entre os múltiplos slaves. Vários slaves podem ser adicionados ou retirados “a quente” da solução, para dimensionamento de capacidade. Se o master cair, os slaves ativos continuarão servindo requisições e voltarão a receber atualizações automaticamente, quando o master estiver ativo novamente.

Muito bom, heim? Por onde começar?

Ativar a replicação entre instâncias do Redis é bem simples. Vamos começar iniciando duas instâncias distintas:

[sourcecode language=”bash”]
~$ redis-server –port 5550 –daemonize yes
~$ redis-server –port 5551 –daemonize yes
[/sourcecode]

Temos duas instâncias em execução, nas portas 5550 e 5551, que ainda não estão conectadas entre si. Agora vamos habilitar a replicação, executando:

[sourcecode language=”bash”]
~$ redis-cli -p 5551 SLAVEOF localhost 5550
[/sourcecode]

Pronto. A instância da porta 5551 está registrada como slave da instância na porta 5550, que assume o papel de master. Vamos testar a replicação, inserindo um dado no master e, em seguida, consultar o slave.

[sourcecode language=”bash”]
~$ redis-cli -p 5550 SET teste-master “devo aparecer no slave”
OK
~$ redis-cli -p 5551 GET teste-master
“devo aparecer no slave”
[/sourcecode]

Se tudo deu certo, suas instâncias do Redis estão prontas para operar com replicação e permitir um uso bastante versátil em suas soluções de software.


No terceiro e último post desta série, vamos falar um pouco mais sobre escalabilidade horizontal com Redis e algumas estratégias de implementação.