Evitando a troca no ElastiCache Redis

14

Temos tido problemas contínuos com a troca de instância do ElastiCache Redis. A Amazon parece ter algum monitoramento interno bruto, que notifica a troca de picos de uso e simplesmente reinicia a instância do ElastiCache (perdendo assim todos os nossos itens em cache). Aqui está o gráfico de BytesUsedForCache (linha azul) e SwapUsage (linha laranja) em nossa instância do ElastiCache nos últimos 14 dias:

Redis ElastiCache BytesUsedForCache and Swap

Você pode ver o padrão de crescente uso de swap que parece acionar reinicializações de nossa instância do ElastiCache, em que perdemos todos os nossos itens armazenados em cache (BytesUsedForCache cai para 0).

A guia 'Eventos de cache' do painel do ElastiCache possui entradas correspondentes:

ID da fonte | Tipo | Data Evento

ID da instância de cache | cluster de cache | Ter 22 de setembro 07:34:47 GMT-400 2015 | Nó de cache 0001 reiniciado

ID da instância de cache | cluster de cache | Ter 22 de setembro 07:34:42 GMT-400 2015 | Erro ao reiniciar o mecanismo de cache no nó 0001

ID da instância de cache | cluster de cache | Dom 20 de setembro 11:13:05 GMT-400 2015 | Nó de cache 0001 reiniciado

ID da instância de cache | cluster de cache | Qui 17 de setembro 22:59:50 GMT-400 2015 | Nó de cache 0001 reiniciado

ID da instância de cache | cluster de cache | Qua 16 de setembro 10:36:52 GMT-400 2015 | Nó de cache 0001 reiniciado

ID da instância de cache | cluster de cache | Ter 15 de setembro 05:02:35 GMT-400 2015 | Nó de cache 0001 reiniciado

(cortar entradas anteriores)

A Amazon afirma :

SwapUsage - no uso normal, nem o Memcached nem o Redis devem executar swaps

Nossas configurações relevantes (não padrão):

  • Tipo de instância: cache.r3.2xlarge
  • maxmemory-policy: allkeys-lru (estávamos usando o volátil-lru padrão anteriormente sem muita diferença)
  • maxmemory-samples: 10
  • reserved-memory: 2500000000
  • Verificando o comando INFO na instância, vejo mem_fragmentation_ratioentre 1,00 e 1,05

Entramos em contato com o suporte da AWS e não recebemos muitos conselhos úteis: sugeriram aumentar ainda mais a memória reservada (o padrão é 0 e temos 2,5 GB reservados). Como não temos replicação ou instantâneos configurados para esta instância de cache, acredito que nenhum BGSAVE deve estar ocorrendo e causando uso adicional de memória.

O maxmemorylimite de um cache.r3.2xlarge é de 62495129600 bytes e, embora atingimos reserved-memoryrapidamente nosso limite (menos o nosso ), parece-me estranho que o sistema operacional host se sinta pressionado a usar tanta troca aqui e com tanta rapidez, a menos que A Amazon aumentou as configurações de troca do SO por algum motivo. Alguma idéia de por que estaríamos causando tanto uso de troca no ElastiCache / Redis ou solução alternativa que poderíamos tentar?

Josh Kupershmidt
fonte

Respostas:

7

Como ninguém mais tinha resposta aqui, pensei em compartilhar a única coisa que funcionou para nós. Primeiro, essas idéias não funcionaram:

  • tipo de instância de cache maior: estava tendo o mesmo problema em instâncias menores que o cache.r3.2xlarge que estamos usando agora
  • ajustes maxmemory-policy: nem volátil-lru nem allkeys-lru pareciam fazer alguma diferença
  • batendo maxmemory-samples
  • batendo reserved-memory
  • forçando todos os clientes a definir um tempo de expiração, geralmente no máximo 24 horas, com alguns chamadores raros permitindo até 7 dias, mas a grande maioria dos chamadores usando o tempo de expiração de 1 a 6 horas.

Aqui está o que finalmente fez ajuda, muito: a execução de um trabalho a cada doze horas que corre um SCAN sobre todas as chaves em pedaços ( COUNT) de 10.000. Aqui está o BytesUsedForCache dessa mesma instância, ainda uma instância cache.r3.2xlarge sob uso ainda mais pesado do que antes, com as mesmas configurações de antes:

BytesUsedForCache

As quedas no uso da memória correspondem aos horários do trabalho cron. Durante esse período de duas semanas, nosso uso de swap atingiu ~ 45 MB (atingiu ~ 5 GB antes de reiniciar antes). E a guia Eventos de cache no ElastiCache não reporta mais eventos de reinicialização de cache.

Sim, isso parece um argumento que os usuários não deveriam ter que fazer por si mesmos, e que os Redis devem ser inteligentes o suficiente para lidar com essa limpeza por conta própria. Então, por que isso funciona? Bem, o Redis não faz muita ou nenhuma limpeza preventiva de chaves expiradas, em vez disso, depende do despejo de chaves expiradas durante os GETs . Ou, se o Redis perceber que a memória está cheia, ele começará a despejar as chaves para cada novo SET, mas minha teoria é que nesse momento o Redis já está na mangueira.

Josh Kupershmidt
fonte
Josh, querendo saber se você teve mais algum progresso ao trabalhar nessa questão? Estamos passando por uma situação semelhante. Você ainda está usando a mesma solução de antes?
Andrew C
@AndrewC ainda temos essa mesma instância de cache, com comportamento semelhante ao dos dentes de serra dos SCANs e apenas alguns picos de uso de troca persistentes nos últimos 3 meses - nem de longe tão ruins quanto eu postei na pergunta, principalmente devido ao descarregamento atividade fora dessa instância, e o SCANtrabalho na resposta ainda está provocando limpeza. Agora, a AWS oferece recursos do Redis Cluster , que eu aposto que ajudariam para uso pesado.
Josh Kupershmidt 15/02
bom de se ouvir; adotamos uma abordagem semelhante para descarregar a carga do cache em caches separados. Qual é sua hipótese sobre como o clustering ajudaria a reduzir o uso de swap? Apenas reduzindo a carga geral?
Andrew C
@JoshKupershmidt your my hero.
Moriarty
1

Eu sei que isso pode ser antigo, mas eu me deparei com isso na documentação do aws.

https://aws.amazon.com/elasticache/pricing/ Eles afirmam que o r3.2xlarge possui 58,2 gb de memória.

https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/ParameterGroups.Redis.html Eles afirmam que a memória máxima do sistema é 62gb (é quando a política de memória máxima entra em ação) e que não pode ser alterada . Parece que não importa com o Redis na AWS, trocaremos ..

tlindhardt
fonte
A AWS está certa - eles dizem que maxmemory é 62495129600bytes, que é exatamente 58,2 GiB. A página de preços que você vinculou tem memória em unidades de GiB, não em GB. O maxmemoryparâmetro não é modificável, presumivelmente porque há melhores botões fornecidos pelo Redis, como reserved-memory(embora isso não me ajudou ...), que são modificáveis, e não AWS não quero que você misconfiguring o nó por exemplo dizendo Redis para use mais memória do que a VM Elasticache realmente possui.
Josh Kupershmidt 15/08/19