我想了解一下,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时的正确行为吗?
答案 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。你能得到你读过的博客的链接吗?