Redis客户端如何实现流水线操作?

时间:2011-10-28 13:25:06

标签: redis

在Redis protocol documentation中声明:

  

客户端可以使用相同的连接来发布多个   命令。支持流水线操作,因此可以发送多个命令   通过客户端的单个写操作,不需要读取   服务器回复以发出下一个命令。所有回复   可以在最后阅读。

但是,我找不到任何实际实现方法的例子。 Redis客户端如何实现流水线操作?

3 个答案:

答案 0 :(得分:5)

可以在下面分别列出的Ruby redis客户端redis-rb和Python的redis-py之一的源代码中找到一些关于如何实现它的简单示例。

它们基本上完成了TaylorOtwell上面提到的内容,将客户端将在管道中进行redis的请求连接到单个网络请求,而事务将使用redis命令MULTI / EXEC开始和结束交易。

redis-rb (来自redis.rbpipeline.rb):

def pipelined(options = {})
  synchronize do
    begin
      original, @client = @client, Pipeline.new
      yield
      if @client.commands.empty?
        []
      else
        original.call_pipelined(@client.commands, options)
      end
    ensure
      @client = original
    end
  end
end

def call_pipelined(commands, options = {})
  @commands.concat commands
  nil
end

另一个很好的例子可以在Python {redis}客户端redis-py的源代码中找到。希望有所帮助。

答案 1 :(得分:4)

只要您可以轻松划分TCP流上的消息,服务器支持流水线操作几乎不需要支持,TCP堆栈将为您缓冲数据,作为服务器,您只需读取/解析请求一个接一个,并在完成请求后发回回复。客户端/服务器只需要知道并处理这些缓冲区填满的情况,而不是死锁。

那就是说,对于redis来看看networking.c中的processInputBuffer()/ processMultibulkBuffer(),redis也有自己的输出缓冲,参见例如addReply()

答案 2 :(得分:2)

只是对上述答案提出更多见解。理解redis管道的一种方法是理解redis管道完全是客户端实现的事实,而redis服务器与它无关。虽然这在不同的客户端实现中有所不同,但这是一般概念:

Pipelining旨在解决高网络延迟环境中的响应延迟问题。因此,在发送命令和读取响应时花费在网络上的时间越少越好。这通过缓冲有效地实现。在将客户端发送到服务器之前,客户端可以(或可以不)缓冲TCP堆栈上的命令(如其他答案中所述)。一旦将它们发送到服务器,服务器就会执行它们并在服务器端缓冲它们。与通常在收到响应后客户端读取响应的情况不同,在流水线操作的情况下,客户端部分地从服务器端缓冲区读取响应,或者当应用程序执行“sync”(关闭管道)时。这是有利的,因为客户在阅读回复时在网络上花费的时间要少得多。

这是我博客上的帖子,您可以参考以获得更好的主意: http://nachivpn.blogspot.in/2014/11/redis-pipeline-explained.html