2011-04-18 7 views
6

J'essayais de mettre une charge importante sur mes Redis à des fins de test et de trouver des limites supérieures. D'abord, je l'ai chargé avec 50 000 et 100 000 clés de taille 32 caractères avec des valeurs d'environ 32 caractères. Il n'a pas fallu plus de 8-15 secondes dans les deux tailles de clés. Maintenant, j'essaie de mettre 4kb de données en valeur pour chaque clé. Les 10000 premières touches prennent 800 millisecondes à régler. Mais à partir de ce moment, il ralentit progressivement et mettre 50 000 touches entières, cela prend environ 40 minutes. Je charge la base de données en utilisant NodeJs avec node_redis (Mranney). Y at-il une erreur que je fais ou est-ce que Redis est aussi lent avec de grandes valeurs de taille 4 Ko? Une autre chose que je trouve maintenant est quand je lance un autre client parallèle à celui actuel et que les clés de mise à jour ce 2ème client finit par charger les 50000 clés avec des valeurs de 4kb en 8 secondes alors que le premier client fait toujours son truc. Est-ce un bug dans le noeud ou la bibliothèque redis? C'est alarmant et inacceptable pour la production.Problèmes de performances Redis?

+0

Utilisez-vous hiredis? – generalhenry

+0

Hmm .. J'ai installé hiredis mais je ne sais pas s'il est automatiquement chargé dans le programme quand j'en ai besoin ('redis'). Est-ce le problème? – Lalith

+0

Pour vérifier si le module hiredis est installé, vous pouvez exécuter node, puis require ("hiredis") '. –

Répondre

5

Vous aurez besoin d'une sorte de contre-pression pour effectuer des écritures en bloc à partir du noeud dans Redis. Par défaut, le noeud met en file d'attente toutes les écritures et n'applique pas de limite supérieure à la taille de la file d'attente sortante. Node_redis a un événement "drain" que vous pouvez écouter pour mettre en place une contre-pression rudimentaire.

+0

Bonjour Matt, j'ai essayé de regarder client.command_queue.length et arrêter jusqu'à ce que je reçois un événement "drain". client.command_queue.length est toujours 0. Donc je vérifiais client.offline_queue.length qui me donne le bon numéro mais l'évènement drain ne se déclenche qu'une seule fois, je vais essayer à nouveau et revenir avec le code Merci – Lalith

+0

J'ai joint le code ici https://gist.github.com/945441 Cela ne semble pas être le bon moyen de backpressure? – Lalith

+2

Il ya un couple de questions différentes ici.La première est que les commandes de pré-connexion sont mises en file d'attente. La seconde est qu'une fois que vous avez une connexion, une autre file est maintenue pour les commandes envoyées mais pour lesquelles une réponse n'a pas encore été reçue. J'ai ajouté un exemple d'une manière générale de traiter les deux cas ici: https://github.com/mranney/node_redis/blob/master/examples/backpressure_drain.js –

3

La configuration redis par défaut n'est pas optimisée pour ce type d'utilisation. Je suppose que vous l'avez swap sur le disque avec une taille de page de 32 octets, ce qui signifie que chaque clé ajoutée doit trouver 128 pages libres contiguës et peut finir par utiliser VM système ou avoir besoin de développer le fichier d'échange beaucoup. Lorsque vous mettez à jour une clé, l'espace est déjà alloué afin que vous ne voyiez aucun problème de performances.

+0

Ceci est juste à des fins de test, donc je m'en fous. Mais que se passe-t-il si une telle demande se produit en temps réel et que mon application doit stocker autant de données? Y a-t-il une configuration que je peux modifier pour correspondre à mes exigences? – Lalith

+0

Aussi même avant que le premier client ait créé toutes les 50000 clés Si je cours le 2ème client il avance et finit avant le 1er. Donc, ce que vous avez dit n'est peut-être pas le problème auquel je suis confronté. – Lalith

+3

La taille de la page et l'utilisation de la mémoire sont configurables - vérifiez les commentaires dans redis.conf. Le deuxième client final n'élimine pas nécessairement ce scénario - la combinaison de conditions de faible mémoire et de concurrence peut devenir assez complexe, en particulier si des délais et des tentatives automatiques sont impliqués. Par exemple, pourrait-il être réinitialiser toutes les clés précédentes chaque fois qu'il se heurte à une erreur? –

0

Depuis que je fais beaucoup de jeu (valeur de clé) dans NodeJs qui est fait de manière asynchrone, beaucoup de connexions socket sont simultanément ouvertes. Le tampon d'écriture de la socket NodeJs peut être surchargé et GC peut venir et manipuler le processus de nœud. PS: J'ai changé les configurations de mémoire redis comme Tom l'a suggéré mais il faisait toujours la même chose.

Questions connexes