[Tiago Motta] Estratégias de persitência do Redis

Nestes ultimos meses eu ministrei algumas palestras sobre o uso de redis na prática, usando como exemplo algumas funcionalidades do Musica.com.br. Uma das dúvidas mais constantes nesses eventos é a questão das opções de persistência deste banco. Confesso que não havia estudado o suficiente sobre o assunto. Eis que com o crescimento do site, surgiu a necessidade de uma estratégia melhor sobre a manutenção desses dados. Então aproveitei minhas horas em aeroportos para realizar alguns testes e responder algumas dúvidas.

Pra começar o Redis possui três formas de persitência de dados: não persistir, dump no disco e append only. O dump no disco, basicamente consiste em gravar uma cópia da memória em disco de tempos em tempos. O append only grava todos os comandos em um log, de forma que para recuperar em caso de restarte ele refaz todo o caminho percorrido.

Vamos então às perguntas que eu me fazia, e as respostas que obtive com meus testes:

1) É possível converter o rdb (dump) para um aof (appendonly)?

Sim para isso é preciso executar o comando BGREWRITEAOF estopar o redis server e estartar de novo com a nova configuração habilitada para appendonly.

2) O tempo para gravar e carregar o rdb (dump) é grande?

Para os padrões do Redis gravar é sim um tempo grande. Mas talvez não seja algo que possa atrapalhar. Depende muito da quantidade de dados que sua base terá. Fiz um teste adicionando três vezes 1 milhão de registros e comparando o tempo que demorava para gerar o dump em disco. Essa tabela pode servir de guia para saber quando é o momento de colocar o seu redis em uma máquina separada, e quando é hora de trocar de estratégia de gravação.

Registros Memória Disco Tempo para salvar Gravação de Memória/segundo
1.000.000 99.94M 24M 0.56s 178.46 M/s
2.000.000 191.50M 42M 0.93s 205.37 M/s
3.000.000 283.03M 62M 1.32s 214.41 M/s

No entanto, o load do dump com 3 milhões de registros foi irrisório.

3) O tempo para carregar o aof (appendonly) é grande?

Sim, muito grande. Fiz um teste similar ao do dump, com 3 milhões de registros colocando 313.57M em memória e gerando um arquivo aof de 192M. Ao restartar o servidor ele demorou 4 segundos para carregar o arquivo. Um resultado que achei péssimo. No entanto, se pensarmos que restartar servidor é algo que não faremos com tanta constância, pode não ser algo tão ruim. Só deve-se ficar em mente que manutenções desse tipo em uma base grande devem ser em horários com pouco ou nenhum uso do seu servidor master.

4) É possivel compactar o aof (appendonly) com BGREWRITEAOF?

Um dos problemas do aof é que se um registro for incluido e removido, as duas instruções serão gravadas, de forma que não há uma razão clara entre memória do servidor e tamanho do arquivo em disco gerado. Minha dúvida era se eu poderia limpar o aof reescrevendo somente aquilo que estava na memória. E sim, isso é possível com o comando BGREWRITEAOF.

5) Os comandos ficam mais lentos com aof (appendonly) ligado?

Sim. Fiz um teste com concorrência. Três processos inserindo 1 milão de itens em listas diferentes. Com rdb (dump) habilitado a média de tempo foi de 0.33s. Com aof (appendonly) habilitado e rdb (dump) desabilitado a média de tempo foi de 0.43s. Essa proporção de 30% mais demorado para aof foi constante nos três testes seguintes que fiz como tira-teima.

6) Se o redis slave ficar down por um tempo ele recebe os dados do master?

Sim, fiz uma série de testes e percebi que o redis slave ignora os arquivos salvos por ele mesmo. Sempre que se inicia ele recebe todos os dados novamente do master, seja ele configurado como rdb ou como aof. Portanto, se estiver utilizando master slave, uma boa é configurar o seu slave para não gravar nada.

7) Gravar o rdb (dump) afeta a performance na resposta a outros comandos?

Sim, fiz um teste gravando três vezes uma memória de 2GB enquanto estava inserindo 1 milhão de novos registros. A insersão deles demorou 25% mais que inserir a mesma quantidade de registros sem salvar nenhuma vez o rdb. Só para se ter uma idéia, o tempo de gravação deste dump foi de 9 segundos e o tempo de load foi de 4 segundos.

Conclusão:

- Manter seus dados com rdb deixa o redis mais rápido, mas pode exigir muito de IO nos intervalos de persistência. Se a memória estiver muito grande, vale a pena colocar o servidor master em uma máquina dedicada para que não atrapalhe outros serviços.

- Manter seus dados com aof deixa o redis mais lento, mas garante que nenhuma transação será perdida. É preciso ficar atento para o arquivo gerado e periodicamente compactar ele com BGREWRITEAOF. Também tomar cuidado nos restarts que podem demorar.