redis管道在pyredis中如何工作?

时间:2015-10-22 01:49:13

标签: redis

我想了解一下,redis中的管道衬里是如何工作的?根据我读过的一篇博客,对于这段代码

Pipeline pipeline = jedis.pipelined();
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
    pipeline.set("" + i, "" + i);
}
List<Object> results = pipeline.execute();

Every call to pipeline.set() effectively sends the SET command to Redis (you can easily see this by setting a breakpoint inside the loop and querying Redis with redis-cli). The call to pipeline.execute() is when the reading of all the pending responses happens.

所以基本上,当我们使用pipe-lining时,当我们执行上面设置的任何命令时,命令会在服务器上执行,但在执行之前我们不收集响应,即pipeline.execute()。

但是,根据pyredis的文档, Pipelines are a subclass of the base Redis class that provide support for buffering multiple commands to the server in a single request.

我认为,这意味着,我们使用流水线操作,当我们执行pipe.execute()时,所有命令都被缓冲并发送到服务器,因此这种行为与上述行为不同。

有人可以告诉我使用pyreids时的正确行为吗?

2 个答案:

答案 0 :(得分:1)

这不仅仅是一个redis-py的东西。在Redis中,流水线始终意味着缓冲一组命令,然后一次性将它们发送到服务器。流水线操作的要点是避免无关的网络来回 - 经常是针对Redis运行命令时的瓶颈。如果在管道运行之前将每个命令发送到Redis,则情况并非如此。

您可以在实践中对此进行测试。打开python并:

import redis
r = redis.Redis()
p = r.pipeline()
p.set('blah', 'foo') # this buffers the command. it is not yet run.
r.get('blah') # pipeline hasn't been run, so this returns nothing.
p.execute()
r.get('blah') # now that we've run the pipeline, this returns "foo".

答案 1 :(得分:0)

我确实运行了您在博客中描述的测试,但我无法重现该行为。 在for循环中设置断点,然后运行

redis-cli info | grep keys
每次设置命令后

都不会显示大小增加。

说到这一点,你粘贴的代码似乎是使用Jedis的Java(我也使用过)。 在我运行的测试中,根据文档,jedis中没有 execute()方法,但 exec() sync()一个。

我确实看到在 sync()命令后以redis设置的值。

此外,this question似乎与pyredis文档一起使用。

最后,redis documentation本身侧重于网络优化(引用示例)

  

这一次,我们不会为每次通话支付RTT的费用,而只需支付三次命令的费用。

P.S。你能得到你读过的博客的链接吗?