2017-04-20 5 views
1

ich Redis lerne, und ich bin mit dem Pipelining-Konzept blockiert, ich versuche Anweisung an meinem redis ServerRedis Pipelining 200 Anweisungen gesendet, nur 189 Antworten

Muss ich whitch einen Sockel mit bis zu senden, so wird die Verbindung zum der Redis-Server, den ich verwende.

Hier ist mein Code (ich bin Französisch so werden einige Worte in französisch sein)

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 

Und hier ist die Art, wie ich die Pipelining bin mit:

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) 

, wenn ich das tue, die Shell gibt mir den 200 INCR compteur aber es wird gefolgt mit:

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

Hat jemand eine Erklärung? Auch wenn ich einen anderen Befehl zum Beispiel mit einem GET compteur verwende, habe ich nur 147 + PONG

+2

Warum verwenden Sie nicht einen Redis-Adapter für Python statt Sockets von Hand zu definieren? https: // GitHub.com/andymccurdy/redis-py –

+0

Ich kann den Redis-Adaptator nicht benutzen, weil dieser Code auf einer SPS implementiert wird, die nicht mit redis versehen wird, es wird nur python haben, also muss ich das tun, aber danke für der Ratschlag –

Antwort

0

Sie hinzufügen können zwei Befehle umgeben Ihr instraction: MULTI vor und EXEC nach Ihren Anweisungen. Dies garantiert die Atomarität und alle Ergebnisse der Ausführung Ihrer Befehle. Werfen Sie einen Blick auf transaction Dokumentation.

Bitte lesen Sie über pipelining auch. Hier gibt es viele nützliche Informationen.

In der Tat, ich denke Ihr Problem ist, dass Sie die Antwort lesen konnten, bevor Redis es zurückgibt.

Obwohl Logik des Flusses submitRequest -> receiveResults sieht gut aus, aber Ihr Code funktioniert nicht auf diese Weise, da Redis Vorgang asynchron ausführen.

In der Tat liest Ihr Code auf die nächste Art: Senden von Daten (Anweisungen) an Server-> Lesen Sie einige Daten aus Socket (Ergebnis | Teil des Ergebnisses | nichts?). Die Probleme bestehen darin, dass wir Redis nicht warten, bis die Berechnung abgeschlossen ist.

Ich bin nicht gut in Python, aber ich denke, data = s.recv(BUFFER_SIZE) wird bis 'BUFFER_SIZE' Bytes von s lesen, wenn es vorhanden ist. Wenn jedoch nur ein Teil der Ergebnisse im Socket vorhanden ist, gibt dieser Befehl nur diesen Teil der Daten zurück. Lesen von Socket ist nicht so trivial Operation, wie andere Leute vorschlagen - verwenden bereits vorhandene Bibliotheken - https://redis.io/clients#python

+0

Danke für die Antwort, ich habe nicht bemerkt, dass mein Puffer so klein ist, ich habe ihn einfach erhöht und es funktioniert perfekt. Ich lese über das Pipelining jetzt kann es eine große Verbesserung für meinen Code sein. –

0

Wie Edgar vorgeschlagen, verwenden Sie die redis-py Python-Bibliothek, um Ihre Redis-Verbindungen zu verwalten.

das Verwenden von:

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) 

richtig zeigt 100 Pongs (oder True), wie erwartet.

oder ein ähnlicher Test mit INCR:

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

results = pipe.execute() 

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

kehrt:

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

Danke dizzyf, aber ich kann diese Methode nicht verwenden, dieses Programm wird in einem Roboter hochgeladen, der nicht mit redis ausgestattet wird, wird es nur "kleine" Anweisung "sprechen", wie ich schrieb. Aber danke für die Antworten, ich werde es ein anderes Programm verwenden. –

Verwandte Themen