...

Redis LFU vs LRU: Qual é a política de evicção mais adequada?

O LFU e o LRU do Redis determinam quais as chaves que são removidas da cache quando os recursos são escassos – e, assim, decidem sobre Taxa de acerto, tempo de resposta e consumo de memória. Vou mostrar-te quando é que a política LFU, orientada para a frequência, ou a política LRU, orientada para a atualidade, é mais adequada, como as configurar e quais os efeitos que as políticas «allkeys-lfu» e «allkeys-lru» têm no dia-a-dia; a palavra-chave principal Redis LFU está no centro desta questão.

Pontos centrais

  • Recência vs. Frequência: O LRU dá prioridade aos acessos mais recentes, enquanto o LFU dá prioridade aos acessos mais frequentes.
  • Aproximação No Redis: ambas as políticas funcionam com amostras através da variável `maxmemory-samples`.
  • Cargas de trabalho escolher: Sessões/Painéis → LRU, Mais vendidos/Classificações → LFU.
  • Afinação É importante definir corretamente os parâmetros: lfu-decay-time, maxmemory e maxmemory-samples.
  • Monitorização Necessário: verificar continuamente a taxa de acertos, as expulsões por segundo e a latência.

Como funciona a evicção no Redis

O Redis armazena os dados na RAM; se o processo memória máxima, tem de eliminar chaves. É precisamente aqui que entram em ação políticas como a «allkeys-lru» e a «allkeys-lfu», que determinam quais as entradas que têm de ser eliminadas. Concentro-me nestas duas variantes porque têm em conta todo o conjunto de dados, e não apenas as chaves com TTL. O Redis seleciona a chave a eliminar através de uma amostra, que pode definir com maxmemory-samples controla; um maior número de amostras aumenta a precisão, mas consome recursos da CPU. Esta abordagem proporciona bons resultados em grandes espaços de chaves, sem tornar a gestão demasiado dispendiosa.

Informações internas: como o Redis implementa os algoritmos LRU e LFU

Ambas as políticas funcionam no Redis aproximadamente, para manter uma velocidade constante. O LRU armazena, para cada objeto, um registo da data e hora do último acesso. Na evicção, o Redis faz uma amostragem e descarta o candidato „mais antigo“ da seleção. Na prática, isto é extremamente eficiente e suficientemente preciso, desde que se escolha o tamanho da amostra adequado ao espaço de chaves.

Redis LFU complementa esta ideia com uma medidor de frequência compacto, que ao longo do tempo envelhece (Decay). Cada acesso aumenta o contador de utilizações de forma não linear, mas sim atenuada, para que as fases de pico isoladas não saturam o contador de forma permanente. Ao mesmo tempo, uma decadência temporal garante que a popularidade passada acabe por perder peso. Através de parâmetros como lfu-decay-time (a que velocidade a história fica desatualizada) e um fator de registo interno (em que medida os contadores aumentam a cada acesso) é que deves equilibrar rapidez de reação contra Estabilidade da priorização. Regra a reter: valores de decaimento mais baixos → adaptação mais rápida; valores mais elevados → prioridades mais lentas, mas mais estáveis.

LRU no Redis: princípio, vantagens, armadilhas

O LRU remove o elemento mais antigo não utilizados Chaves e, assim, dá prioridade à atualidade. Esta lógica adapta-se a padrões com localização temporal, como sessões, painéis em tempo real ou respostas de API a curto prazo. O Redis utiliza um LRU aproximado: as entradas têm uma marca temporal e as amostragens selecionam o candidato mais antigo – de forma rápida e compreensível. O LRU reage rapidamente às alterações, porque as chaves utilizadas recentemente permanecem no topo e as mais antigas são removidas. Podem tornar-se problemáticas as grandes varreduras pontuais, que enchem a cache com valores de curta duração e chaves importantes que estão temporariamente inativas reprimir.

Dica prática: se utilizares o LRU e executares regularmente consultas em massa „frias“ (por exemplo, relatórios de back-office), isola essas cargas de trabalho em separado Caches ou planeia-as de forma mais generosa memória máxima-reservas. Desta forma, evitas a «poluição da cache», em que dados valiosos, que em breve voltarão a ser necessários, são substituídos.

LFU no Redis: princípio, vantagens e armadilhas

O LFU remove chaves com baixa Frequência de utilização protegendo assim as „teclas de atalho“ a longo prazo. O contador interno cresce de forma logarítmica e envelhece com o tempo (decadência), para que a popularidade antiga não conte para sempre. Isto leva a uma ponderação equilibradora: os dados utilizados com frequência permanecem armazenados por mais tempo, enquanto valores atípicos isolados quase não alteram a prioridade. O LFU proporciona frequentemente uma taxa de acertos mais elevada em catálogos, classificações ou caches de características, uma vez que mantém na memória as chaves comprovadas. No entanto, reage de forma mais lenta a novas tendências, razão pela qual o ajuste de lfu-decay-time continua a ser importante.

Para Tendências em alta e em baixa (por exemplo, campanhas de marketing) aplica-se o seguinte: defina o «decay» de forma a que uma nova tendência tenha um impacto percetível, sem que o ruído pontual reorganize constantemente a cache. Em muitos projetos, o que tem dado bons resultados é: começar de forma conservadora e, em seguida, acelerar gradualmente até que a taxa de acertos se mantenha estável sob carga.

Comparação: Recência vs. Frequência no dia-a-dia

No fundo, o LRU distingue „quando foi utilizado pela última vez“ e o LFU „quantas vezes foi utilizado“ – eu escolho com base nos dados reais Cargas de trabalho. No caso de dados voláteis e próximos do utilizador, o LRU costuma funcionar de forma mais natural, uma vez que os acessos recentes antecipam frequentemente os acessos futuros. Para dados de produtos ou configurações populares, o LFU funciona melhor, porque o que conta é a popularidade duradoura. Em cenários mistos, separo as caches por tipos de dados e aplico políticas diferentes. A tabela seguinte resume sucintamente as diferenças e dá-te uma visão rápida Apoio à decisão.

Aspeto LRU (allkeys-lru) LFU (allkeys-lfu)
Prioridade Atualidade o número de visitas Frequência o número de visitas
Reação à mudança de padrão Depressa, porque o que conta é a última utilização Moderado, uma vez que o histórico tem influência
Cargas de trabalho recomendadas Sessões, painéis de controlo, APIs em tempo real Best-sellers, classificações, caches em destaque
Sensibilidade à „poluição“ Bastante elevado em digitalizações de grande dimensão Bastante reduzida graças ao contador de frequências
Parafusos de ajuste maxmemory-samples lfu-decay-time, maxmemory-samples
Explicabilidade Muito intuitivo Bem, no que diz respeito ao Decay

Impactos no desempenho na prática

No caso de pequenos conjuntos de dados, a diferença costuma ser baixo; à medida que o tamanho aumenta, o joio separa-se do trigo. O LRU convence pelo baixo custo de CPU da aproximação e por uma causa clara: uma chave é eliminada porque foi a última a ficar sem ser utilizada. O LFU destaca-se em acessos consistentes, uma vez que as chaves «quentes» permanecem seguramente na RAM e a taxa de acertos aumenta de forma mensurável. O desafio reside na compreensão necessária dos contadores e do decaimento, para que não reajas nem de forma demasiado lenta nem demasiado agressiva. Verifico os efeitos através de análise de desempenho e métricas, em vez de me basear apenas na intuição decidir.

Planeia também o Arranque a frio : Após reinícios ou implementações, a cache fica vazia ou „desinformada“ quanto às frequências. A LRU estabiliza-se rapidamente com base na localidade a curto prazo. A LFU, por natureza, necessita de um certo período de aquecimento para identificar as verdadeiras «chaves quentes». Estratégias como Pré-aquecimento (carregar proativamente as chaves importantes) ou um aumento gradual do tráfego ajudam a atenuar a latência inicial e as falhas.

Configuração e ajuste: as opções mais importantes

Escolho a política através de política de memória máxima, normalmente allkeys-lru ou allkeys-lfu, mais raramente variantes voláteis com foco no TTL. Com memória máxima Defino o limite rígido a partir do qual a evicção começa e dimensiono-o em função do conjunto de dados, acrescido de uma margem de segurança. Controlo a dimensão da amostra através de maxmemory-samples; valores mais elevados melhoram a seleção, mas consomem recursos da CPU. Para o LFU, é lfu-decay-time é fundamental, porque determina a rapidez com que os acessos antigos perdem importância e os novos ganham peso. Podes encontrar aqui um guia detalhado sobre o dimensionamento da memória: Configurar a memória de forma ideal.

Sugestões concretas para a prática

Para um arranque rápido, trabalho com predefinições claras e faço iterações sob carga:

  • allkeys-lru + maxmemory-samples 7–10 para dados voláteis e próximos do utilizador
  • Redis LFU (allkeys-lfu) + lfu-decay-time conservador (por exemplo, um valor moderado) para cargas de trabalho estáveis com teclas de atalho

Definir a configuração em tempo de execução:

CONFIG SET maxmemory 8gb
CONFIG SET maxmemory-policy allkeys-lru
CONFIG SET maxmemory-samples 10
# Mudança para LFU:
CONFIG SET maxmemory-policy allkeys-lfu
CONFIG SET lfu-decay-time 5

No ficheiro redis.conf, define-se essas mesmas opções de forma permanente. Eu testo primeiro as alterações no ambiente de teste com uma carga representativa, antes de as aplicar no ambiente de produção.

Selecionar o tamanho da amostra

maxmemory-samples É um parâmetro de ajuste fiável: valores mais elevados melhoram a qualidade dos resultados dos candidatos à evicção, mas consomem CPU. Como regra geral, começo com 7–10 em espaços de chaves grandes e só reduzo se o tempo de CPU estiver escasso. Em espaços de chaves pequenos, 5 amostras costumam ser suficientes.

Monitorização e métricas: medir em vez de adivinhar

Estou sempre atento Taxa de acerto, despejos, latências e utilização de memória, para avaliar a interação entre estes fatores. Se as evicções aumentarem significativamente, verifico as reservas de RAM, as estratégias de TTL e a política selecionada. Uma taxa de acertos em queda indica frequentemente que mudanças nos padrões de utilização estão a enfraquecer a política atual ou que os conjuntos de dados não estão a ser armazenados em cache de forma suficientemente separada. Os picos de latência indicam, por vezes, que a Amostras ou a uma evicção demasiado agressiva. Os testes de carga regulares ajudam-me a encontrar o equilíbrio certo entre a carga da CPU, o limite de memória e a taxa de acerto.

Comandos práticos para verificações rápidas:

INFO stats     # keyspace_hits, keyspace_misses, evicted_keys, expired_keys
INFO memory    # used_memory, fragmentation, allocator_overhead
LATENCY DOCTOR # Notas sobre picos, por exemplo, bifurcação ou E/S

O Taxa de acerto Calculo-o como «acertos / (acertos + erros)». Uma taxa em queda, acompanhada de um aumento dos despejos, constitui um sinal de alerta. chaves_despejadas em relação ao tráfego e memória_utilizada indica se a política tem de ser ativada com frequência. Com Chave «MEMORY USAGE» identificas objetos de tamanho excessivo que ocupam uma parte desproporcional da tua cache.

Aspectos relacionados com o alojamento e a escalabilidade: escolher a plataforma de forma consciente

O Redis revela os seus pontos fortes numa de alto desempenho Plataforma com bastante memória RAM, baixa latência e ligação de rede fiável. Em projetos em expansão, evito o funcionamento contínuo a plena carga, porque isso faz com que a evicção seja acionada com demasiada frequência e a taxa de acertos seja prejudicada. Uma boa Estratégia de alojamento garante que as políticas sejam aplicadas quando necessário e não funcionem de forma contínua. Nas comparações, aposto em fornecedores premium como o webhoster.de, cuja infraestrutura suporta bem cargas elevadas e permite uma capacidade previsível. Assim, a plataforma contribui diretamente para menos evictions e melhor Tempos de resposta e um desempenho mais constante.

Aspectos relacionados com clusters e réplicas

Em configurações de sharding (por exemplo, Redis Cluster), as decisões de evicção são aplicadas por nó. Ou seja: a margem de segurança, a política e o ajuste têm de ser adequados para cada nó, e não apenas „em média“. As chaves de acesso rápido que estão distribuídas de forma desigual pelos slots podem levar determinados nós ao limite mais cedo. Por isso, planeie buffers por fragmento e monitorize as evicções ao nível dos nós. As réplicas assumem o estado dos dados, incluindo as chaves eliminadas; tenha em conta, nos testes de carga, que a replicação adicional pode aumentar as latências, sem que a política em si seja a responsável por isso.

Estratégias TTL e políticas mistas

Com o TTL, protejo os de longa duração Configurações e dou prioridade aos dados sensíveis ao tempo e de curta duração. Se utilizar o «volatile-lru» ou o «volatile-lfu», o Redis apenas substitui as chaves com tempo de validade – o que é útil quando o cache e os valores permanentes coexistem. Costumo separar as caches por tipos de dados: sessões em LRU, catálogos de produtos em LFU, para tirar partido dos respetivos pontos fortes. Uma escolha inteligente do TTL evita que entradas desatualizadas ocupem memória RAM desnecessariamente e provoquem evicções. Assim, mantenho a memória limpa, sem perder dados úteis Teclas de atalho para perder.

Importante: uma política é válida por instância. É possível aplicar políticas diferentes consoante o tipo de dados de forma fiável, utilizando instâncias Redis separadas ou caches claramente delimitadas. Os namespaces, por si só, não alteram a política; no entanto, ajudam na invalidação seletiva e na medição.

Análise prática: Começar com LRU, transição seletiva para LFU

Costumo começar com LRU, porque é intuitivo e proporciona resultados rápidos. Em seguida, identifico as caches com teclas de atalho permanentes e mudo seletivamente para o LFU. Esta abordagem minimiza o risco, porque só se fazem alterações nos casos em que os padrões de dados realmente beneficiam da lógica de frequência. Com canaries e testes A/B, medo a taxa de acertos e a latência antes e depois da mudança. Assim, otimizo passo a passo, em vez de alterar todo o Plataforma fazer a transição de uma só vez.

Um percurso de migração comprovado

  • Estabelecer uma linha de base: registar a taxa de acerto atual, as expulsões e os percentis 95.º e 99.º da latência.
  • Selecionar a cache piloto: área estável, com maior volume de leitura e teclas de atalho bem definidas.
  • Ativar o LFU, lfu-decay-time definir de forma conservadora, maxmemory-samples aumentar.
  • Prever uma fase de aquecimento e acompanhar o processo até que os valores se estabilizem.
  • Comparar as métricas e só depois proceder ao ajuste, em pequenos passos.

Dificuldades frequentes nas aplicações (por exemplo, o WordPress)

Nos sistemas de conteúdo, os TTL incorretos e os Chaves o que pode rapidamente levar a uma avalanche de «evictions». Verifica se as páginas dinâmicas estão a ser armazenadas em cache sem querer ou se valores demasiado grandes estão a esgotar a memória. Certifica-te de que o comportamento de invalidação após as publicações é correto, para que os conteúdos desatualizados desapareçam e se liberte espaço. Este guia ajuda-te a identificar erros típicos no ambiente do CMS: Erro no cache de objetos. Se invalidares corretamente, definires TTLs realistas e escolheres a política adequada, a taxa de acertos e Velocidade mensurável.

Outros anti-padrões da prática:

  • Grandes imóveis individuais (por exemplo, blocos enormes de JSON) ocupam o espaço de muitas chaves pequenas e úteis. Solução: dividir os dados e armazenar em cache apenas os segmentos efetivamente utilizados.
  • Fogão trovejante: Muitas falhas simultâneas na mesma chave. Solução: aglomeração de pedidos/bloqueios, pequenas variações nos TTLs, para que as renovações ocorram de forma distribuída.
  • Poluição por digitalização: Leituras em lote sem reutilização. Solução: Instância/espaço de nomes separado, LRU nesse espaço com memória mais generosa ou optar por não armazenar as cargas de trabalho em cache.
  • Invalidação pouco clara: As versões antigas ocupam espaço na cache. Solução: esquemas de chaves claros (por exemplo, prefixos de versão) e percursos determinísticos de invalidação.

Resumo: Como faço a escolha

Eu fixo LRU quando a atualidade constitui a melhor heurística para acessos futuros – por exemplo, no caso de sessões, painéis e APIs em tempo real. Recorro a isso LFU, quando existem teclas de atalho claras e permanentes que também pretendo proteger em picos de carga. A monitorização mostra-me se as evicções estão a tornar-se excessivas ou se a taxa de acerto está a diminuir; nesse caso, ajusto as amostras, os TTLs e o decaimento. Com uma escolha criteriosa da plataforma, um limite de memória bem definido e caches separados por tipo de dados, consigo obter sempre o máximo rendimento. Desta forma, o cache mantém-se rápido, previsível e adequado ao padrão de acesso – sem qualquer margem para suposições.

Artigos actuais

Visualização de uma cache Redis com servidores e fluxos de dados para ilustrar as políticas de evicção LFU e LRU
Bases de dados

Redis LFU vs LRU: Qual é a política de evicção mais adequada?

Para configurar a tua cache da melhor forma, deves compreender como funciona a evicção do Redis com o Redis LFU e o Redis LRU – este artigo apresenta-te uma comparação direta e ajuda-te a escolher a política adequada.