Redis e Memcache ou apenas Redis?

85

Estou usando memcached para algum cache em meu aplicativo Rails 3 por meio da Rails.cacheinterface simples e agora gostaria de fazer algum processamento de trabalho em segundo plano com redis e resque.

Acho que são diferentes o suficiente para justificar o uso de ambos. No entanto, no heroku, há taxas separadas para usar o memcached e o redis. Faz sentido usar os dois ou devo migrar para apenas usar o redis?

Eu gosto de usar o memcached para armazenamento em cache porque as chaves menos usadas recentemente são automaticamente excluídas do cache e não preciso que os dados do cache persistam. Redis é basicamente novo para mim, mas entendo que é persistente por padrão e que as chaves não expiram do cache automaticamente.

EDIT: Só queria ser mais claro com minha pergunta. Eu sei que é viável usar apenas Redis em vez de ambos. Acho que só quero saber se há alguma desvantagem específica em fazer isso. Considerando a implementação e a infraestrutura, há algum motivo para eu não usar apenas o Redis? (Ou seja, o memcached é mais rápido para cache simples?) Não encontrei nada definitivo de qualquer maneira.

markquezada
fonte
5
Para qualquer outra pessoa que esteja considerando isso: há um plugin redis store para rails que permite usar o redis como um armazenamento de cache.
markquezada de

Respostas:

49

Supondo que a migração do memcached para o redis para o cache que você já faz seja fácil o suficiente, optaria pelo redis apenas para manter as coisas simples.

No redis, a persistência é opcional, portanto, você pode usá-la de maneira muito semelhante ao memcached, se for o que deseja. Você pode até descobrir que tornar o cache persistente é útil para evitar muitas perdas de cache após uma reinicialização. Expiry também está disponível - o algoritmo é um pouco diferente do memcached, mas não o suficiente para importar para a maioria dos propósitos - veja http://redis.io/commands/expire para detalhes.

Tom Clarkson
fonte
1
Obrigado pela resposta e os documentos relevantes. Editei minha pergunta um pouco para deixar mais claro o que estou procurando. Não pensei sobre a persistência do cache depois de reiniciar ... esse é um bom recurso. (Embora eu não tenha certeza de quão útil é, considerando que eu usaria o redis para ir com o heroku.)
markquezada
1
Se você quiser manter alguns itens efêmeros (cache de fragmento) e alguns itens persistentes no redis, você precisa criar duas instâncias separadas do redis?
Brian Armstrong
1
Embora usemos o Redis para filas de tarefas e cache, nós os executamos com configurações diferentes, especificamente pelos motivos que @BrianArmstrong afirma. O cache é efêmero, então o configuramos como sendo rápido, mas não há problema em perder coisas na memória e descartar LRU. Para a fila, realmente não queremos perder jobs, então a configuramos com persistência para que seja recuperável.
jwadsack
@jwadsack você tem um post onde mostra como você implementou essa configuração?
Marklar
1
@Marklar Boa ideia. Eu faço agora: ballardhack.wordpress.com/2015/09/30/…
jwadsack
44

Sou o autor do redis-store , não há necessidade de usar comandos do Redis diretamente, basta usar a :expires_inopção como esta:

ActionController::Base.cache_store = :redis_store, :expires_in => 5.minutes

A vantagem de usar o Redis é a rapidez e, com a minha joia, é que você já tem lojas para Rack::Cache, Rails.cacheou I18n.

Luca Guidi
fonte
Obrigado pela resposta Luca. Estou assumindo que você pode substituir: expires_in diretamente quando precisar armazenar algo persistentemente? Eu acho que a questão é realmente sobre usar a funcionalidade do tipo memcached e usar o redis como um armazenamento persistente um ao lado do outro.
markquezada
3
Não acho que faça sentido ter memcached e redis ao lado, já que eles estão no mesmo segmento NoSQL: ambos são uma loja k / v. Redis PROS: 1. mais rápido que memcached 2. comandos mais poderosos 3. nenhum aquecimento de cache necessário 4. útil para resolver outros problemas (por exemplo, filas com Resque) CONTRAS: 1. você precisa de um gem externo 2. após uma reinicialização, o servidor não aceita comandos ao ler dados do arquivo anexado Memcached PROS: cozido no Rails CONTRAS: 1. mais lento que o Redis 2. aquecimento do cache.
Luca Guidi,
3
@LucaGuidi Atualmente estou usando o RedisStore para meu cache Rails. Não consigo descobrir como definir o URL do Redis e o padrão :expires_in. Você pode ajudar?
Chris Vincent
Como eu, se você estiver enfrentando problemas para configurar :expires_inusando redis_store, consulte stackoverflow.com/questions/20907247/…
Anirudhan J
19

Eu vi alguns sites grandes de rails que usam Memcached e Redis. Memcached é usado para coisas efêmeras que são boas para manter quentes na memória, mas podem ser perdidas / regeneradas se necessário, e Redis para armazenamento persistente. Ambos são usados ​​para aliviar a carga do banco de dados principal para operações pesadas de leitura / gravação.

Mais detalhes:

Memcached: usado para cache de página / fragmento / resposta e está ok para atingir o limite de memória no Memcached porque ele irá LRU (usado menos recentemente) para expirar o material antigo e frequentemente manter as chaves acessadas ativas na memória. É importante que tudo no Memcached possa ser recriado a partir do banco de dados, se necessário (não é sua única cópia). Mas você pode continuar despejando coisas nele, e o Memcached descobrirá quais são os usados ​​com mais frequência e os manterá ativos na memória. Você não precisa se preocupar em remover coisas do Memcached.

redis: você usa isso para dados que não deseja perder e é pequeno o suficiente para caber na memória. Isso geralmente inclui tarefas resque / sidekiq, contadores para limitação de taxa, resultados de teste de divisão ou qualquer coisa que você não queira perder / recriar. Você não quer exceder o limite de memória aqui, então você deve ser um pouco mais cuidadoso com o que armazena e limpa mais tarde.

O Redis começa a ter problemas de desempenho quando ultrapassa o limite de memória (corrija-me se estiver errado). É possível resolver isso configurando o Redis para agir como Memcached e LRU expirar coisas, de modo que nunca alcance seu limite de memória. Mas você não gostaria de fazer isso com tudo o que mantém no Redis, como recolocar empregos. Então, em vez de as pessoas frequentemente manterem o padrão, Rails.cache definido para usar Memcached (usando o dalligem). E então eles mantêm uma variável global $ redis = ... separada para fazer operações de redis.

# in config/application.rb
config.cache_store = :dalli_store  # memcached

# in config/initializers/redis.rb
$redis = $redis = Redis.connect(url: ENV['REDIS_URL'])

Pode haver uma maneira fácil de fazer tudo isso no Redis - talvez tendo duas instâncias separadas do Redis, uma com um limite de memória de disco rígido LRU, semelhante ao Memcache, e outra para armazenamento persistente. Eu não vi isso usado, mas acho que seria possível.

Brian Armstrong
fonte
15

Eu consideraria verificar minha resposta sobre este assunto:

Rails e cache, é fácil alternar entre memcache e redis?

Essencialmente, por meio de minha experiência, eu defenderia mantê-los separados: memcached para cache e redis para estruturas de dados e armazenamento mais persistente

efalcao
fonte
Embora eu inicialmente planejasse consolidá-los com base na resposta original à minha pergunta, desde então cheguei basicamente à mesma conclusão. Estou usando memcache para cache básico e redis para resque.
markquezada
6

Perguntei à equipe do Redis Labs (que fornece os complementos Memcached Cloud e Redis Cloud ) sobre qual produto eles recomendariam para o armazenamento em cache do Rails. Eles disseram que, em geral, recomendariam o Redis Cloud, que o Memcached Cloud é oferecido principalmente para fins legados, e apontaram que o serviço do Memcached Cloud é, na verdade, construído sobre o Redis Cloud.

Yarin
fonte
Portanto, não há necessidade de memcached e redis, conforme mencionado na resposta de Brian? "as pessoas geralmente mantêm o Rails.cache padrão definido para usar memcached (usando a gem dalli). E então eles mantêm uma variável global $ redis = ... separada para fazer operações de redis."
Marklar
4

Não sei para que você os está usando, mas na verdade usar ambos pode lhe dar uma vantagem de desempenho: Memcached tem um desempenho muito melhor rodando em vários núcleos do que Redis, portanto, armazenar em cache os dados mais importantes com Memcached e manter o resto no Redis , tirando proveito de seus recursos como banco de dados, pode aumentar o desempenho.

Slezica
fonte
1
Isso não é totalmente verdade - o redis usa várias instâncias em vez de vários threads, portanto, comparar uma instância redis de núcleo único com uma instância memcached de vários núcleos não é um teste particularmente relevante. Além disso, quando benchmarks estão disponíveis mostrando que os dois sistemas são os mais rápidos, é improvável que a diferença faça diferença no mundo real.
Tom Clarkson
A abordagem de multiprocessos do redis é melhor escalonada em sistemas multi core do que a abordagem (padrão) de memcached com multi-threading: antirez.com/post/update-on-memcached-redis-benchmark.html
Ludger Sprenker
3
Essa grande deficiência do Redis é muito minimizada. Se você estiver procurando por alta simultaneidade e tiver muitos núcleos, o Memcached pode fazer círculos em torno do Redis. Sharding não é uma boa solução, pois você precisa implementar hashing consistente em seu aplicativo e não obterá uma distribuição perfeita entre as instâncias do Redis. Por exemplo, se o fragmento A armazena em cache a configuração do seu aplicativo que é usado em cada solicitação, o fragmento A obterá mais solicitações do que os outros fragmentos que não são atingidos para cada solicitação.
ColinM