Nous exécutons une application Web et sommes passés de memcached à redis (2.4) pour la mise en cache. Maintenant, nous sommes quelque peu déçus par les performances de redis. Redis fonctionne sur le même serveur et nous n'utilisons que des opérations GET et SET très simples. Sur certaines demandes qui font un usage intensif des valeurs mises en cache, nous avons jusqu'à 300 demandes GET à redéfinir, mais ces demandes prennent jusqu'à 150 ms. Nous avons environ 200 000 clés actives et environ 1 000 requêtes redis par seconde. Il n'y a pas de problème avec le disque io, ram ou cpu. En raison de notre code existant, nous ne pouvons pas simplement regrouper les demandes redis ensemble. Memcached a été environ 4 fois plus rapide. Ce que nous aimons à propos de redis, c'est que nous n'avons pas besoin de réchauffement du cache et que nous pourrions utiliser des fonctionnalités de magasin de données plus avancées à l'avenir. Nous nous attendions à ce que redis fonctionne de manière similaire à memcached. Alors peut-être que nous avons manqué quelque chose dans notre configuration, qui est essentiellement la configuration par défaut.
Connaissez-vous une meilleure pratique pour l'optimisation des performances de redis?
Tout d'abord, vous voudrez peut-être lire la page de référence de Redis . Il fournit un bon résumé des principaux points à vérifier pour régler Redis.
Même en supposant que vous n'utilisez pas de pipelining, 300 GET en 150 ms ne sont pas aussi efficaces. Cela signifie que la latence moyenne est de 500 us. Cependant, cela dépend en fait de la taille de vos objets. Objets plus gros, plus de latence. Sur ma très ancienne box AMD 2 GHz, je peux mesurer 150 latences us pour de petits objets (quelques octets).
Pour vérifier rapidement la latence moyenne de l'instance Redis, vous pouvez utiliser:
$ redis-cli --latency
Assurez-vous d'utiliser une version récente de Redis (pas 2.4) pour obtenir cette option. Remarque: 2.4 est assez ancien maintenant, utilisez Redis 2.6 - compilez votre propre version de Redis si nécessaire, c'est vraiment simple.
Pour exécuter rapidement un benchmark pour étudier la latence, vous pouvez lancer:
$ redis-benchmark -q -n 10000 -c 1 -d average_size_of_your_objects_in_bytes
Il fonctionne avec une connexion unique et sans pipeline, de sorte que la latence peut être déduite du débit. Essayez de comparer le résultat de ces repères aux chiffres mesurés avec votre application.
Il y a un certain nombre de points que vous voudrez peut-être vérifier:
Pourquoi est-ce mieux avec memcached? Eh bien, une seule instance memcached est certainement plus évolutive et peut être plus réactive qu'une seule instance Redis, car elle peut s'exécuter sur plusieurs threads. Redis est rapide, mais monothread - l'exécution de toutes les commandes est sérialisée. Ainsi, lorsqu'une commande est en cours pour une connexion, tous les autres clients doivent attendre - une mauvaise latence sur une commande donnée aura également un impact sur toutes les commandes en attente. En général, à faible débit, les performances sont cependant comparables.
À 1000 q/s (un faible débit par les normes Redis ou memcached), je dirais qu'il est plus probable que votre problème soit côté client (ie choix de la bibliothèque client, connexion/déconnexion, etc ...), qu'avec Redis serveur lui-même.
Enfin, je dois mentionner que si vous générez un certain nombre de requêtes Redis par requête HTTP, envisagez pipelining les commandes que vous envoyez à Redis autant que possible. C'est vraiment un point clé pour développer des applications Redis efficaces.
Si vos serveurs d'applications sont sur la même boîte que Redis, vous pouvez également utiliser des sockets de domaine Unix au lieu du bouclage TCP pour vous connecter à Redis. Il améliore légèrement les performances (jusqu'à 50% de débit en plus lorsque le pipelining n'est PAS utilisé).
Vérifiez si redis utilise la mémoire d'échange du système d'exploitation. Si c'est le cas, cela ajoutera de la latence. Pour le savoir, recherchez "Latence induite par l'échange" ici: http://redis.io/topics/latency
Si le matériel de votre serveur est compatible NUMA, il vaut mieux démarrer redis-server avec numactl. N'oubliez pas de désactiver le mode de récupération de zone (vm.zone_reclaim_mode = 0) dans sysctl si vous démarrez avec redis-server avec NUMA.
Essayez de créer un script pour cette requête 300 GET dans un script Lua. Il devrait fonctionner plus rapidement car vous gagnez du temps sur la pile TCP/IP, même si votre code client s'exécute localement sur Redis.