Redis 流水线发送 200 条指令,只有 189 个答案
Redis pipelining 200 instructions sent, only 189 answers
我正在学习 Redis,但我对流水线概念感到困惑,我正在尝试向我的 Redis 服务器发送指令
这样做,我使用套接字连接到我正在使用的 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)
当我这样做时,shell 给了我 200 INCR compteur,但后面跟着:
:1
:2
:3
:4
....
:185
:186
:187
:188
:189
有人有解释吗?另外,如果我使用另一条指令,例如 GET compteur,我只有 147 +PONG
按照 Edgar 的建议,使用 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 个 PONG(或 True
)。
或使用 INCR
的类似测试:
for j in xrange(100):
pipe.incr("test-incr", 1)
results = pipe.execute()
print len(results)
print results[95:100]
returns:
100
[96, 97, 98, 99, 100]
您可以在指令周围添加两个命令:指令前的 MULTI 和指令后的 EXEC。这将保证原子性并获得执行命令的所有结果。查看 transaction 文档。
另请阅读 pipelining。这里有很多有用的信息。
事实上我猜你的问题是你可以在 Redis return 之前开始阅读答案。
虽然流程 submitRequest -> receiveResults 的逻辑看起来不错,但是您的代码不能以这种方式工作,因为 Redis 执行异步操作。
事实上,您的代码以下一种方式读取:将数据(指令)发送到服务器-> 从套接字读取一些数据(结果 | 结果的一部分 | 什么都没有?)。问题是我们不等待 Redis 完成计算。
我不擅长 Python,但我猜 data = s.recv(BUFFER_SIZE)
最多可以从 s
中读取 'BUFFER_SIZE' 个字节(如果存在)。但是,如果只有部分结果出现在套接字中,则此命令 return 只有这部分数据。正如其他人所建议的那样,处理从套接字中读取数据并不是那么简单——使用已经存在的库——https://redis.io/clients#python
我正在学习 Redis,但我对流水线概念感到困惑,我正在尝试向我的 Redis 服务器发送指令
这样做,我使用套接字连接到我正在使用的 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)
当我这样做时,shell 给了我 200 INCR compteur,但后面跟着:
:1
:2
:3
:4
....
:185
:186
:187
:188
:189
有人有解释吗?另外,如果我使用另一条指令,例如 GET compteur,我只有 147 +PONG
按照 Edgar 的建议,使用 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 个 PONG(或 True
)。
或使用 INCR
的类似测试:
for j in xrange(100):
pipe.incr("test-incr", 1)
results = pipe.execute()
print len(results)
print results[95:100]
returns:
100
[96, 97, 98, 99, 100]
您可以在指令周围添加两个命令:指令前的 MULTI 和指令后的 EXEC。这将保证原子性并获得执行命令的所有结果。查看 transaction 文档。
另请阅读 pipelining。这里有很多有用的信息。
事实上我猜你的问题是你可以在 Redis return 之前开始阅读答案。
虽然流程 submitRequest -> receiveResults 的逻辑看起来不错,但是您的代码不能以这种方式工作,因为 Redis 执行异步操作。
事实上,您的代码以下一种方式读取:将数据(指令)发送到服务器-> 从套接字读取一些数据(结果 | 结果的一部分 | 什么都没有?)。问题是我们不等待 Redis 完成计算。
我不擅长 Python,但我猜 data = s.recv(BUFFER_SIZE)
最多可以从 s
中读取 'BUFFER_SIZE' 个字节(如果存在)。但是,如果只有部分结果出现在套接字中,则此命令 return 只有这部分数据。正如其他人所建议的那样,处理从套接字中读取数据并不是那么简单——使用已经存在的库——https://redis.io/clients#python