Redis et Memcache ou juste Redis?

85

J'utilise memcached pour la mise en cache dans mon application Rails 3 via l' Rails.cacheinterface simple et j'aimerais maintenant faire un traitement de travail en arrière-plan avec redis et resque.

Je pense qu'ils sont suffisamment différents pour justifier l'utilisation des deux. Sur heroku cependant, il y a des frais distincts pour utiliser à la fois memcached et redis. Est-il judicieux d'utiliser les deux ou devrais-je migrer simplement vers Redis?

J'aime utiliser Memcached pour la mise en cache car les clés les moins récemment utilisées sont automatiquement expulsées du cache et je n'ai pas besoin que les données du cache persistent. Redis est principalement nouveau pour moi, mais je comprends qu'il est persistant par défaut et que les clés n'expirent pas automatiquement du cache.

EDIT: Je voulais juste être plus clair avec ma question. Je sais qu'il est possible d'utiliser uniquement Redis au lieu des deux. Je suppose que je veux juste savoir s'il y a des inconvénients spécifiques à le faire? Compte tenu à la fois de la mise en œuvre et de l'infrastructure, y a-t-il des raisons pour lesquelles je ne devrais pas simplement utiliser Redis? (Ie, Memcached est-il plus rapide pour une simple mise en cache?) Je n'ai rien trouvé de définitif de toute façon.

markquezada
la source
5
Pour tous ceux qui envisagent cela: il existe un plugin redis-store pour les rails qui vous permet d'utiliser redis comme magasin de cache.
markquezada

Réponses:

49

En supposant que la migration de memcached vers redis pour la mise en cache que vous faites déjà est assez facile, j'opterais avec redis uniquement pour garder les choses simples.

Dans Redis, la persistance est facultative, vous pouvez donc l'utiliser un peu comme Memcached si c'est ce que vous voulez. Vous pouvez même trouver que rendre votre cache persistant est utile pour éviter de nombreux échecs de cache après un redémarrage. L'expiration est également disponible - l'algorithme est un peu différent de memcached, mais pas assez pour avoir de l'importance dans la plupart des cas - voir http://redis.io/commands/expire pour plus de détails.

Tom Clarkson
la source
1
Merci pour la réponse et les documents pertinents. J'ai un peu modifié ma question pour préciser ce que je recherche. Je n'ai pas pensé à la persistance du cache après un redémarrage ... c'est une fonctionnalité intéressante. (Bien que je ne sache pas à quel point cela est utile, j'utiliserais redis pour aller avec heroku.)
markquezada
1
Si vous souhaitez conserver certains éléments éphémères (mise en cache de fragments) et certains éléments persistants dans redis, devez-vous créer deux instances redis distinctes?
Brian Armstrong du
1
Bien que nous utilisions Redis à la fois pour les files d'attente de travaux et le cache, nous les exécutons avec différentes configurations pour les raisons spécifiques indiquées par @BrianArmstrong. Le cache est éphémère, nous le configurons donc de manière rapide, mais il est normal de perdre des éléments en mémoire et de supprimer LRU. Pour la file d'attente, nous ne voulons vraiment pas perdre de tâches, nous la configurons donc avec persistance afin qu'elle soit récupérable.
jwadsack
@jwadsack avez-vous un article dans lequel vous montrez comment vous avez implémenté cette configuration?
Marklar
1
@Marklar Bonne idée. Je fais maintenant: ballardhack.wordpress.com/2015/09/30/…
jwadsack
44

Je suis l'auteur de redis-store , il n'est pas nécessaire d'utiliser directement les commandes Redis, utilisez simplement l' :expires_inoption comme celle-ci:

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

L'avantage d'utiliser Redis est la solidité, et avec ma gemme, c'est que vous avez déjà des magasins pour Rack::Cache, Rails.cacheou I18n.

Luca Guidi
la source
Merci pour la réponse Luca. Je suppose que vous pouvez remplacer: expires_in directement lorsque vous devez stocker quelque chose de manière persistante? Je suppose que la question concerne vraiment l'utilisation à la fois de la fonctionnalité de type memcached et de l' utilisation de redis comme magasin persistant les uns à côté des autres.
markquezada
3
Je ne pense pas qu'il soit logique d'avoir à la fois memcached et redis à côté, car ils sont dans le même segment NoSQL: les deux sont un magasin ak / v. Redis PROS: 1. plus rapide que memcached 2. commandes plus puissantes 3. pas de préchauffage du cache nécessaire 4. utile pour résoudre d'autres problèmes (par exemple les files d'attente avec Resque) INCONVÉNIENTS: 1. vous avez besoin d'un gem externe 2. après un redémarrage, le serveur n'accepte pas les commandes lors de la lecture des données du fichier d'ajout Memcached PROS: cuit dans Rails CONS: 1. plus lent que Redis 2. préchauffage du cache.
Luca Guidi
3
@LucaGuidi J'utilise actuellement RedisStore pour mon cache Rails. Je ne peux pas comprendre comment définir à la fois l'URL Redis et la valeur par défaut :expires_in. Pouvez-vous m'aider?
Chris Vincent
Comme moi, si vous rencontrez un problème lors de la configuration de :expires_inredis_store, reportez-vous à stackoverflow.com/questions/20907247/…
Anirudhan J
19

J'ai vu quelques grands sites de rails qui utilisent à la fois Memcached et Redis. Memcached est utilisé pour les choses éphémères qui sont agréables à garder en mémoire mais qui peuvent être perdues / régénérées si nécessaire, et Redis pour le stockage persistant. Les deux sont utilisés pour soulager la base de données principale pour les opérations lourdes de lecture / écriture.

Plus de détails:

Memcached: utilisé pour la mise en cache de page / fragment / réponse et il est possible d'atteindre la limite de mémoire sur Memcached car il LRU (le moins récemment utilisé) expirera les anciens éléments et gardera fréquemment les clés accédées au chaud en mémoire. Il est important que tout ce qui se trouve dans Memcached puisse être recréé à partir de la base de données si nécessaire (ce n'est pas votre seule copie). Mais vous pouvez continuer à y déposer des éléments, et Memcached déterminera ceux qui sont les plus utilisés et les gardera en mémoire. Vous n'avez pas à vous soucier de supprimer des éléments de Memcached.

redis: vous l'utilisez pour des données que vous ne voudriez pas perdre et qui sont suffisamment petites pour tenir en mémoire. Cela inclut généralement les tâches resque / sidekiq, les compteurs de limitation de débit, les résultats de test fractionnés ou tout ce que vous ne voudriez pas perdre / recréer. Vous ne voulez pas dépasser la limite de mémoire ici, vous devez donc faire un peu plus attention à ce que vous stockez et nettoyez plus tard.

Redis commence à souffrir de problèmes de performances une fois qu'il dépasse sa limite de mémoire (corrigez-moi si je me trompe). Il est possible de résoudre ce problème en configurant Redis pour qu'il agisse comme Memcached et LRU expire, afin qu'il n'atteigne jamais sa limite de mémoire. Mais vous ne voudriez pas faire cela avec tout ce que vous gardez dans Redis, comme les emplois de resque. Ainsi, au lieu que les gens conservent souvent la valeur par défaut, Rails.cache est configuré pour utiliser Memcached (en utilisant le dalligem). Et puis ils gardent une variable globale $ redis = ... séparée pour faire des opérations redis.

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

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

Il pourrait y avoir un moyen simple de faire tout cela dans Redis - peut-être en ayant deux instances Redis distinctes, une avec une limite de mémoire dure LRU, similaire à Memcache, et une autre pour le stockage persistant? Je n'ai pas vu cela utilisé, mais je suppose que ce serait faisable.

Brian Armstrong
la source
15

J'envisagerais de vérifier ma réponse à ce sujet:

Rails et mise en cache, est-il facile de basculer entre Memcache et Redis?

Essentiellement, grâce à mon expérience, je recommanderais de les garder séparés: memcached pour la mise en cache et redis pour les structures de données et un stockage plus persistant

efalcao
la source
Bien que j'aie initialement prévu de les consolider sur la base de la réponse originale à ma question, j'en suis depuis à peu près à la même conclusion. J'utilise memcache pour la mise en cache de base et redis pour le resque.
markquezada
6

J'ai demandé à l'équipe de Redis Labs (qui fournit les modules complémentaires Memcached Cloud et Redis Cloud ) quel produit ils recommanderaient pour la mise en cache Rails. Ils ont déclaré qu'en général, ils recommanderaient Redis Cloud, que Memcached Cloud est principalement proposé à des fins héritées, et ont souligné que leur service Memcached Cloud est en fait construit sur Redis Cloud.

Yarin
la source
Donc pas besoin de memcached et de redis comme mentionné dans la réponse de Brian? "les gens gardent souvent le paramètre par défaut Rails.cache pour utiliser memcached (en utilisant le gem dalli). Et puis ils gardent une variable globale $ redis = ... séparée pour faire des opérations redis."
Marklar
4

Je ne sais pas pour quoi vous les utilisez, mais en fait, utiliser les deux peut vous donner un avantage en termes de performances: Memcached a de bien meilleures performances sur plusieurs cœurs que Redis, donc mettre en cache les données les plus importantes avec Memcached et conserver le reste dans Redis , tirant parti de ses capacités de base de données, pourrait augmenter les performances.

slezica
la source
1
Ce n'est pas tout à fait vrai - redis utilise plusieurs instances plutôt que plusieurs threads, donc comparer une instance redis à un seul cœur avec une instance multi-core memcached n'est pas un test particulièrement pertinent. En outre, lorsque des points de repère sont disponibles, montrant que les deux systèmes sont les plus rapides, la différence n'a probablement pas d'importance dans le monde réel.
Tom Clarkson
L'approche multi-processus de redis évolue mieux sur les systèmes multi-cœurs que l'approche (par défaut) de memcached avec multi-threading: antirez.com/post/update-on-memcached-redis-benchmark.html
Ludger Sprenker
3
Cette lacune majeure de Redis est vraiment beaucoup minimisée. Si vous recherchez une concurrence élevée et que vous avez de nombreux cœurs, Memcached peut faire tourner des cercles autour de Redis. Le sharding n'est pas une bonne solution car vous devez implémenter un hachage cohérent dans votre application et vous n'obtiendrez pas une distribution parfaite entre les instances Redis. Par exemple, si le fragment A met en cache la configuration de votre application qui est utilisée dans chaque requête, le fragment A recevra plus de demandes que les autres fragments qui ne sont pas atteints pour chaque demande.
ColinM