2017-04-20 58 views
1

我學習Redis的,我封閉的流水線概念,我試圖發送指令到我的Redis服務器Redis的流水線200次的指令發送,只有189回答

做對,所以我使用套接字whitch將連接到我正在使用的redis服務器。

這裏是我的代碼(我是法語,所以有些話會法語)

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 

這裏是我公司採用流水線方式:

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) 

我這樣做的時候,外殼給了我200 INCR compteur但它跟隨:

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

有人有解釋嗎?只有147 + PONG

+2

你爲什麼不使用Redis的適配器,而不是蟒蛇手工定義插座? https://開頭github上。com/andymccurdy/redis-py –

+0

我不能使用redis adaptator,因爲這個代碼將在一個不會提供redis的PLC上實現,它只會有python,所以我必須這樣做,但是謝謝建議 –

回答

0

您可以添加兩個命令環繞你instraction:多前,你的指令後,EXEC。這將保證原子性並獲得執行命令的所有結果。看看transaction文檔。請參閱pipelining。這裏有很多有用的信息。

事實上,我猜你的問題是你可以在Redis返回之前開始閱讀答案。

雖然流動submitRequest的邏輯 - > receiveResults看起來不錯,但因爲Redis的異步地進行操作您的代碼不會以這種方式工作。

事實上,你的代碼讀取下一方式:發送數據(指令)服務器 - >從套接字讀取一些數據(結果|結果部分|什麼?)。問題是我們不等Redis完成計算。

我不擅長Python,但我猜data = s.recv(BUFFER_SIZE)會從s讀取'BUFFER_SIZE'字節,如果它存在。但是如果只有部分結果出現在套接字中,這個命令只返回這部分數據。處理來自套接字讀取也不是那麼瑣碎的操作,因爲其他人建議 - 使用已經存在的庫 - https://redis.io/clients#python

+0

謝謝你的回答,我沒有意識到我的緩衝區非常小,我只是增加了它,它完美的工作。 我在閱讀關於流水線的知識,可能對我的代碼有很大的改進。 –

0

埃德加·建議另外,如果我使用例如另一指令用GET compteur,我有,使用redis-py Python庫,以幫助管理您的Redis的連接。

使用的是:

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) 

正確顯示100個PONGs(或True),如所預期。

或類似的測試使用INCR

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

results = pipe.execute() 

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

回報:

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

謝謝dizzyf,但我不能用這個方法,這個程序會上傳到一個不會裝有redis的機器人上,它只會「說」像我寫的那樣的小指令。但是,謝謝你的答案,我會用它一個不同的程序。 –