Guia para Escolher Políticas de Evicção do Redis Eficazes
O Redis é renomado por sua velocidade, em grande parte devido à sua natureza em memória. No entanto, quando seu conjunto de dados cresce maior do que a memória física disponível, o Redis deve remover proativamente dados mais antigos ou menos críticos para abrir espaço para novas entradas. Este processo é gerenciado através das Políticas de Evicção, que são cruciais para manter o desempenho e garantir que seu cache opere de forma ideal. A escolha da política correta impacta diretamente nas taxas de acerto do cache, latência e utilização da memória.
Este guia explora as várias políticas de evicção nativas do Redis, explicando como cada uma funciona e fornecendo conselhos práticos sobre a seleção da estratégia mais eficaz para diferentes cargas de trabalho de aplicação, desde cenários de cache puro até o gerenciamento de dados de séries temporais.
Entendendo a Evicção do Redis e maxmemory
As políticas de evicção só entram em ação quando o uso de memória do Redis excede o limite definido pela diretiva de configuração maxmemory. Se maxmemory não for definido (ou for definido como 0), o Redis usará toda a memória disponível e nenhuma evicção ocorrerá, o que pode levar à instabilidade do sistema se a máquina hospedeira ficar sem RAM.
Para habilitar a evicção, você deve configurar maxmemory no seu arquivo redis.conf ou através do comando CONFIG SET:
# Define maxmemory para 2GB
CONFIG SET maxmemory 2gb
Uma vez que a memória esteja restrita, o Redis usa a política de evicção configurada para decidir quais chaves descartar quando um comando de escrita requer mais memória.
As Políticas de Evicção Nativas do Redis
O Redis oferece várias políticas distintas. Estas são configuradas usando a diretiva maxmemory-policy. As políticas geralmente se enquadram em duas categorias: aquelas baseadas em Menos Recentemente Usado (LRU) ou Menos Frequentemente Usado (LFU), e aquelas que visam chaves com Tempo de Vida (TTL) definido.
1. Políticas Sem Requisitos de TTL
Estas políticas operam em todas as chaves no banco de dados, independentemente de terem ou não um tempo de expiração definido.
noeviction
Esta é a política padrão. Quando o limite de memória é atingido, o Redis rejeita comandos de escrita (como SET, LPUSH, etc.), retornando um erro ao cliente. Leituras (GET) ainda são permitidas. Isso é frequentemente adequado para dados de missão crítica onde a perda de dados é inaceitável, mas pode levar a erros na aplicação sob alta pressão de escrita.
allkeys-lru
Evicta as chaves menos recentemente usadas entre todas as chaves no banco de dados até que o uso da memória esteja abaixo do limite maxmemory. Esta é a escolha padrão para um cache de propósito geral onde todos os itens de dados são igualmente 'cacheáveis'.
allkeys-lfu
Evicta as chaves menos frequentemente usadas entre todas as chaves. LFU prioriza manter chaves que são acessadas com frequência, mesmo que não tenham sido acessadas recentemente. Isso é eficaz quando os padrões de acesso são voláteis, mas itens muito populares podem permanecer residentes indefinidamente.
allkeys-random
Evicta chaves escolhidas aleatoriamente até que o limite de memória seja satisfeito. Raramente é recomendado para caches de produção, a menos que o padrão de acesso aos dados seja completamente uniforme e imprevisível.
2. Políticas que Requerem TTL (Chaves Voláteis)
Estas políticas consideram apenas chaves que possuem um tempo de expiração explícito (EXPIRE ou SETEX) definido. Elas ignoram chaves sem expiração ao realizar a evicção.
volatile-lru
Evicta as chaves menos recentemente usadas entre aquelas que têm uma expiração definida.
volatile-lfu
Evicta as chaves menos frequentemente usadas entre aquelas que têm uma expiração definida.
volatile-random
Evicta uma chave aleatória entre aquelas que têm uma expiração definida.
volatile-ttl
Evicta primeiro a chave com o tempo de vida restante (TTL) mais curto. Isso é ideal para dados sensíveis ao tempo, como tokens de sessão ou estado temporário da aplicação, garantindo que dados mais antigos e prestes a expirar sejam limpos primeiro.
Selecionando a Política Certa para Sua Carga de Trabalho
A política de evicção ideal depende inteiramente do que você está armazenando em cache e de como sua aplicação usa os dados.
| Tipo de Carga de Trabalho | Política Recomendada | Racional |
|---|---|---|
| Cache de Propósito Geral (Mais comum) | allkeys-lru |
Assume que dados mais antigos e não utilizados devem ser removidos primeiro, independentemente do TTL. Simples e altamente eficaz. |
| Dados Sensíveis ao Tempo (ex: tokens, sessões de curta duração) | volatile-ttl |
Garante que as chaves próximas à expiração sejam limpas eficientemente antes que expirem de fato. |
| Cache de Dados 'Quentes' (Alto desvio de acesso) | allkeys-lfu ou volatile-lfu |
Protege itens acessados frequentemente de serem evictados devido à inatividade recente. |
| Retenção Obrigatória de Dados (Nenhuma perda permitida) | noeviction |
Impede a perda de dados ao gerar erro nas escritas, exigindo intervenção manual ou tratamento pela aplicação de origem. |
| Cargas de Trabalho Mistas (Alguns dados expiram, outros não) | volatile-lru ou volatile-ttl |
Se suas chaves sem expiração são essenciais, use uma política volátil para protegê-las, evictando apenas chaves com expiração explícita. |
Exemplo Prático: Implementando um Armazenamento de Sessão
Se o Redis for usado principalmente para armazenar sessões de usuário, você normalmente definiria um TTL explícito em cada chave de sessão (ex: 30 minutos) e usaria uma política que respeita os TTLs. volatile-ttl é frequentemente superior aqui porque, se uma sessão for muito utilizada, ela não deve ser evictada simplesmente por ser um pouco mais antiga do que outra sessão que não é tocada há semanas.
# 1. Define maxmemory (ex: 10GB)
CONFIG SET maxmemory 10gb
# 2. Escolhe a política que visa dados com tempo de vida
CONFIG SET maxmemory-policy volatile-ttl
Exemplo Prático: Implementando um Cache HTTP
Para armazenar em cache respostas HTTP completas (que podem não ter sempre um TTL definido), você deseja manter os dados que são acessados com mais frequência, mesmo que esses dados estejam parados por algumas horas. allkeys-lru ou allkeys-lfu são ideais.
# Usa LFU para reter objetos verdadeiramente 'quentes', independentemente do seu tempo de criação
CONFIG SET maxmemory-policy allkeys-lfu
Monitoramento e Ajuste
Após selecionar uma política, o monitoramento contínuo é essencial. Você deve rastrear as seguintes métricas através do comando INFO:
used_memory: O quão perto você está do limitemaxmemory.evicted_keys: A taxa na qual o Redis está descartando dados. Uma taxa de evicção constantemente alta indica que sua configuraçãomaxmemoryestá muito baixa para sua carga de trabalho, ou sua política de evicção é excessivamente agressiva.- Taxa de Acerto do Cache da Aplicação: A medida final de sucesso. Se sua taxa de acerto cair quando a pressão de memória aumentar, sua seleção de política ou o limite
maxmemoryprecisam de ajuste.
Melhor Prática: Ao ajustar
maxmemory, sempre deixe uma margem de segurança (ex: 10-20% de memória livre) para levar em conta o buffering de replicação, o buffering de comandos e a potencial sobrecarga das estruturas de dados internas do Redis.
Conclusão
As políticas de evicção do Redis fornecem controle granular sobre como seu cache se comporta sob pressão de memória. Não existe uma única política 'melhor'; a escolha entre evicção baseada em LRU, LFU ou TTL deve se alinhar precisamente com seus padrões de acesso a dados e requisitos de negócios. Ao selecionar cuidadosamente a política apropriada—como allkeys-lru para cache geral ou volatile-ttl para armazenamento de sessão—você pode maximizar a eficiência do cache e garantir um desempenho robusto para suas operações de dados de alta velocidade.