Comparando os Tradeoffs de Desempenho entre Persistência AOF e RDB

Compare os tradeoffs de persistência AOF e RDB do Redis em termos de latência, durabilidade, tempo de recuperação, tamanho do arquivo e configuração de produção.

Comparando os Tradeoffs de Desempenho entre Persistência AOF e RDB

A persistência no Redis é um tradeoff entre a quantidade de dados que você pode perder e o trabalho de disco que seu servidor pode absorver. No entanto, quando a persistência está habilitada—permitindo que os dados sejam salvos em disco para recuperação após uma reinicialização—os desenvolvedores devem escolher um mecanismo. Os dois principais métodos de persistência no Redis são Snapshotting (RDB) e o Append-Only File (AOF). Compreender as implicações de desempenho, características de durabilidade e tradeoffs de configuração de cada um é crucial para ajustar o Redis de modo a atender requisitos específicos de velocidade versus segurança de dados.

Snapshots RDB são compactos e rápidos de carregar. O AOF registra as escritas com mais frequência e geralmente oferece melhores pontos de recuperação, mas custa mais I/O de disco.

Entendendo a Persistência no Redis

O Redis armazena todo o seu conjunto de dados em memória volátil. Mecanismos de persistência são necessários para mover esses dados para o disco, de modo que o Redis possa recarregar o conjunto de dados após uma reinicialização, garantindo a disponibilidade dos dados durante interrupções de serviço ou reinicializações. Tanto o RDB quanto o AOF alcançam esse objetivo por meio de abordagens fundamentalmente diferentes, resultando em perfis de desempenho distintos.

1. Snapshotting do Banco de Dados Redis (RDB)

O RDB cria um snapshot compacto e pontual de todo o conjunto de dados em intervalos especificados. Ele salva esses dados em um arquivo binário (dump.rdb).

Como o RDB Funciona e Seu Impacto no Desempenho

A persistência RDB depende fortemente do comando BGSAVE (Background Save). Quando um salvamento é acionado:

  1. Fork: O Redis bifurca o processo principal em um processo filho.
  2. Snapshotting: O processo filho escreve todo o conjunto de dados no arquivo RDB no disco.
  3. Thread Principal Não Afetada (Na Maioria das Vezes): A thread principal do Redis continua atendendo requisições de clientes sem ser bloqueada durante a operação de escrita, pois o filho lida com o I/O de disco.

Considerações de Desempenho:

  • Latência de Escrita: Geralmente, o RDB tem um impacto mínimo na latência de escrita durante a operação de salvamento, pois o trabalho é delegado. O principal custo de desempenho é o pico de CPU e o burst inicial de I/O necessários quando o fork ocorre e durante a escrita do arquivo grande.
  • Tempo de Recuperação: O RDB carrega muito rapidamente após a reinicialização, pois é um único arquivo otimizado, minimizando a latência de recuperação.
  • Tradeoff de Durabilidade: Se o Redis falhar entre salvamentos programados (por exemplo, a cada 5 minutos), todas as escritas ocorridas desde o último salvamento serão perdidas. Isso torna o RDB menos durável que o AOF.

Configurando Salvamentos RDB

Os salvamentos RDB são configurados usando a diretiva save no arquivo redis.conf, especificando intervalos de tempo e o número de alterações:

save 900 1     # Salvar se 1 chave mudou em 900 segundos (15 minutos)
save 300 10    # Salvar se 10 chaves mudaram em 300 segundos (5 minutos)
save 60 10000  # Salvar se 10000 chaves mudaram em 60 segundos (1 minuto)

2. Persistência Append-Only File (AOF)

O AOF registra cada operação de escrita recebida pelo servidor Redis em um arquivo de log de apenas anexação. Quando o Redis reinicia, ele reproduz esses comandos sequencialmente para reconstruir o conjunto de dados.

Como o AOF Funciona e Seu Impacto no Desempenho

Ao contrário do RDB, o AOF foca na registro transacional. O perfil de desempenho depende fortemente da política de fsync, que dita com que frequência o Redis força o sistema operacional a escrever dados em buffer no disco físico.

Políticas de Fsync do AOF:

Política Configuração appendfsync Durabilidade Impacto no Desempenho
A Cada Segundo everysec Boa em operação normal; uma falha pode perder cerca de um segundo de escritas reconhecidas Bom equilíbrio; escolha comum em produção.
Sem Sincronização no Ruim (depende do buffer do SO) Mais rápido; risco máximo de perda de dados em caso de falha do SO.
Sempre always Política de durabilidade AOF mais forte Mais lento; aumento significativo de latência devido à sincronização de disco em cada escrita.

Considerações de Desempenho:

  • Latência de Escrita: Ao usar appendfsync always, cada comando de escrita incorre na latência de uma sincronização de disco, desacelerando significativamente as operações em comparação com o RDB ou operações em memória. Usar everysec mitiga isso significativamente ao agrupar fsyncs.
  • Tempo de Recuperação: Os arquivos AOF podem se tornar grandes e reproduzir milhões de comandos pode levar mais tempo do que carregar um arquivo RDB compacto, resultando em maior latência de recuperação.
  • Tamanho do Arquivo: Os arquivos AOF são tipicamente muito maiores que os arquivos RDB porque armazenam comandos (por exemplo, SET chave valor) em vez do estado final da estrutura de dados.

Habilitando e Configurando o AOF

O AOF está desabilitado por padrão e é habilitado definindo appendonly yes no redis.conf. A configuração crucial é appendfsync:

appendonly yes
appendfilename "appendonly.aof"
# Configuração recomendada para o tradeoff entre durabilidade e velocidade
appendfsync everysec 

Análise de Tradeoff de Desempenho: AOF vs. RDB

Escolher entre RDB e AOF requer priorizar a velocidade operacional bruta (latência) ou a recuperação garantida de dados.

Latência e Throughput

  • RDB (Melhor para Velocidade Bruta): Como as escritas são tratadas por um processo em segundo plano, a thread principal do Redis vê um impacto mínimo de I/O direto durante os salvamentos. Isso geralmente resulta em menor latência de escrita geral, a menos que o sistema esteja fortemente carregado quando o fork do BGSAVE ocorre.
  • AOF (modo always): Esta configuração é a mais lenta porque a latência de disco é introduzida diretamente em cada comando de escrita do cliente, levando a latências p99 mais altas.
  • AOF (modo everysec): Isso fornece desempenho quase semelhante ao RDB para a maioria das operações, pois as operações de fsync são armazenadas em buffer e menos frequentes.

Durabilidade e Risco de Perda de Dados

  • AOF (Melhor para Durabilidade): Fornece a maior durabilidade, especialmente com appendfsync always. Mesmo com everysec, a perda de dados é limitada a um segundo.
  • RDB (Pior para Durabilidade): A perda de dados pode abranger minutos ou horas, dependendo da programação de salvamento.

Tempo de Recuperação

  • RDB (Recuperação Rápida): Tempos de reinicialização mais rápidos devido ao formato binário compacto e otimizado.
  • AOF (Recuperação Mais Lenta): Reproduzir um grande log de comandos pode levar mais tempo do que carregar um snapshot, aumentando o tempo de inatividade durante as reinicializações.

Melhor Prática: Usando Ambos os Métodos de Persistência

Para ambientes que exigem tanto alto desempenho quanto fortes garantias de durabilidade, a abordagem recomendada é habilitar a persistência RDB e AOF simultaneamente.

Quando ambos estão habilitados, o Redis usa o arquivo AOF para reprodução durante a inicialização para alcançar a máxima consistência de dados. Ele continua a gerar snapshots RDB periodicamente.

Por que usar ambos?

  1. Melhores Opções de Recuperação: O Redis normalmente carrega o AOF primeiro quando ambos estão habilitados, pois geralmente é mais completo. Manter o RDB fornece um artefato de fallback extra para backups e recuperação de desastres.
  2. Flexibilidade Operacional: O RDB é compacto e fácil de arquivar, enquanto o AOF reduz a janela de perda de dados. Juntos, eles cobrem diferentes modos de falha.

Trecho de Configuração para Ambos:

# 1. Habilitar RDB
save 900 1

# 2. Habilitar AOF com sincronização 'everysec'
appendonly yes
appendfsync everysec

Gerenciando o Tamanho do Arquivo AOF (Reescrita)

Uma preocupação operacional significativa com o AOF é o crescimento do tamanho do arquivo. Com o tempo, o arquivo AOF pode se tornar enorme, pois registra cada modificação, mesmo aquelas que sobrescrevem valores anteriores. Para combater isso, o Redis oferece a reescrita do AOF.

Reescrita do AOF gera um novo arquivo AOF otimizado que contém apenas o conjunto mínimo de comandos necessários para reconstruir o estado atual do conjunto de dados. Esse processo é acionado automaticamente quando o tamanho do arquivo AOF atual cresce além de um certo múltiplo do tamanho base.

auto-aof-rewrite-percentage 100  # Reescrever quando o arquivo AOF estiver 100% maior que o tamanho base
auto-aof-rewrite-min-size 64mb    # Não reescrever a menos que o arquivo tenha pelo menos 64MB

Aviso sobre Reescrita: Assim como o salvamento RDB, a reescrita do AOF envolve bifurcar o processo. Se o seu sistema tiver restrição de memória, essa duplicação temporária do uso de memória (a instância ativa mais a cópia sendo reescrita) pode levar a instabilidade ou swapping.

Conclusão

Use RDB quando reinicialização rápida, backups compactos e baixa sobrecarga de escrita forem mais importantes do que perder escritas recentes. Use AOF com appendfsync everysec quando você precisar de uma janela de recuperação mais restrita sem sincronizar cada escrita. Para muitos sistemas de produção, habilitar ambos oferece uma combinação prática de durabilidade, conveniência de backup e opções de recuperação.