2017-04-20 4 views
1

J'apprends Redis et je suis bloqué avec le concept de pipelining, je suis en train d'envoyer l'instruction à mon Redis serveurRedis pipelining 200 instructions envoyées, seulement 189 réponses

Do à donc je l'aide d'une prise whitch se connecte à le serveur redis que j'utilise.

Voici mon code (je suis français, donc quelques mots seront en français)

def send(MESSAGE): 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.connect((TCP_IP, TCP_PORT)) 
    s.send(MESSAGE) 
    data = s.recv(BUFFER_SIZE) 
    s.close() 
    print "Envoi requete PC:", MESSAGE 
    return data 

Et voici la façon dont je me sers du pipelining:

instruction ='SET compteur 0' 
donnee = instruction.encode('utf-8') + '\x0D\x0A' 
print envoie(donnee) 
instruction='' 
for i in range(200): 
    instruction = instruction + 'INCR compteur\r\n' 
donnee = instruction.encode('utf-8') + '\x0D\x0A' 
print send(donnee) 

quand je fais cela, le shell me donne le compteur 200 INCR mais il est suivi avec:

:1 
:2 
:3 
:4 
.... 
:185 
:186 
:187 
:188 
:189 

Est-ce que quelqu'un a une explication? Aussi, si j'utilise une autre instruction par exemple avec un compteur GET, je n'ai que 147 + PONG

+2

Pourquoi ne pas utiliser un adaptateur redis pour python? https: // github.com/andymccurdy/redis-py –

+0

Je ne peux pas utiliser l'adaptateur redis parce que ce code sera implémenté sur un automate qui ne sera pas fourni avec redis, il aura seulement python, donc je dois faire comme ça, mais merci pour le conseil –

Répondre

0

Vous pouvez ajouter deux commandes entourent votre instrAction: MULTI avant et après EXEC vos instructions. Cela garantira l'atomicité et obtiendra tous les résultats d'exécution de vos commandes. Jetez un oeil sur la documentation transaction.

S'il vous plaît lire à propos de pipelining aussi. Il y a beaucoup d'informations utiles ici. En fait, je suppose que votre problème est que vous pourriez commencer à lire la réponse avant que Redis ne le renvoie.

Bien que la logique de flux submitRequest -> receiveResults semble bonne, mais votre code ne fonctionne pas de cette façon car Redis effectue une opération de manière asynchrone.

En fait, votre code lit de la manière suivante: envoyer des données (instructions) au serveur-> lire certaines données de la socket (résultat | partie du résultat | rien?). Le problème est que nous n'attendons pas que Redis complète le calcul.

Je ne suis pas bon en Python mais je suppose que data = s.recv(BUFFER_SIZE) lira jusqu'à 'BUFFER_SIZE' octets de s s'il est présent. Mais si seulement une partie des résultats est présente dans le socket, cette commande renvoie uniquement ces parties de données. Pourquoi ne pas utiliser un adaptateur redis pour python au lieu de définir les sockets manuellement? https://redis.io/clients#python

+0

Merci pour la réponse, je n'avais pas réalisé que mon buffer était si petit, je l'ai simplement augmenté et ça fonctionne parfaitement. Je suis en train de lire sur le pipelining maintenant, il peut être une grande amélioration pour mon code. –

0

Comme Edgar l'a suggéré, utilisez la bibliothèque python redis-py pour aider à gérer vos connexions redis.

aide que:

from redis import StrictRedis 

r = StrictRedis(host='localhost', db=1) 
pipe = r.pipeline() 

for i in xrange(100): 
    pipe.ping() 

results = pipe.execute() 

print len(results) 

montre bien 100 PONGS (ou True), comme prévu.

Ou un test similaire en utilisant INCR:

for j in xrange(100): 
    pipe.incr("test-incr", 1) 

results = pipe.execute() 

print len(results) 
print results[95:100] 

retours:

100 
[96, 97, 98, 99, 100] 
+1

Merci dizzyf mais je ne peux pas utiliser cette méthode, ce programme sera uploadé dans un robot qui ne sera pas équipé de redis, il ne "parlera" que de petites instructions comme je l'ai écrit. Mais merci pour les réponses je vais utiliser un programme différent. –