【问题标题】:How do I implement Redis pipelined requests with Booksleeve?如何使用 Booksleeve 实现 Redis 流水线请求?
【发布时间】:2012-10-11 14:51:58
【问题描述】:

我对 Redis 事务和管道之间的区别以及最终如何将管道与 Booksleeve 一起使用有点混淆。我看到Booksleeve 支持 Redis transaction feature (MULTI/EXEC),但在其 API/测试中没有提及流水线功能。但是,在其他实现中很明显管道和事务之间存在区别,即在 atomicity 中,正如下面的 redis-ruby 版本所证明的那样,但在某些 places 中,这些术语似乎可以互换使用。

redis-ruby 实现:

r.pipelined {
  # these commands will be pipelined
  r.get("insensitive_key")
}

r.multi {
  # these commands will be executed atomically
  r.set("sensitive_key")
}

我只是改用MULTI/EXEC,但他们似乎会阻止所有其他用户,直到交易完成(在我的情况下不是必需的),所以我担心他们的表现。有没有人在 Booksleeve 中使用过管道或者对如何实现它们有任何想法?

【问题讨论】:

    标签: c# .net redis booksleeve


    【解决方案1】:

    在 BookSleeve 中,一切始终是流水线式的。没有同步操作。一个都没有。因此,每个操作都会返回某种形式的Task(可以是普通的Task,也可以是Task<string>Task<long> 等),在未来的某个时候(即当redis响应时)将有一个值。您可以在调用代码中使用Wait 来执行同步等待,或使用ContinueWith / await(C# 5 语言功能)来执行异步回调。

    交易也不例外;它们是流水线的。事务的唯一细微变化是它们在调用站点额外缓冲直到完成(因为它是一个多路复用器,我们不能开始管道传输与事务相关的消息,直到我们有一个完整的工作单元,因为它会对同一多路复用器上的其他调用者产生不利影响)。

    所以:没有明确的.pipelined 的原因是一切都是流水线和异步的。

    【讨论】:

      【解决方案2】:

      流水线是一种协议级别的通信策略,与原子性无关。它与“交易”的概念完全正交。 (例如,您可以在管道连接中使用MULTI .. EXEC。)

      什么是流水线?

      redis 最基本的连接器是一个以请求-回复方式交互的同步客户端。客户端发送一个请求,然后等待 Redis 的响应,然后再发送下一个请求。

      在流水线中,客户端可以继续发送请求,而无需暂停查看每个请求的 Redis 响应。 Redis 当然是单线程服务器和自然序列化点,因此请求顺序被保留并反映在响应顺序中。这意味着,客户端可以有一个线程发送请求(通常通过从请求队列中出列),而另一个线程不断处理来自 Redis 的响应。请注意,当然您仍然可以对单线程客户端使用流水线,但您确实会损失一些效率。双线程模型允许充分利用本地 CPU 和网络带宽(例如饱和)。

      如果您到目前为止一直在关注这一点,您必须问自己:那么,请求和响应在客户端是如何匹配的?好问题!有多种方法可以解决这个问题。在 JRedis 中,我将请求包装在 (java) Future 对象中,以处理请求/响应处理的异步性。每次发送请求时,相应的 Future 对象都会被挂起的响应对象包装并排队。响应侦听器一次简单地从该队列中取出 1 个项目并解析响应(流)并更新未来对象。

      现在客户端的最终用户可以使用同步或异步接口。如果接口是同步的,实现自然必须阻塞 Future 的响应。

      如果您到目前为止一直遵循,那么应该清楚的是,使用同步语义和流水线的单线程应用程序违背了流水线的全部目的(因为应用程序阻塞了响应并且没有忙于向客户端提供额外的请求。 ) 但如果应用程序是多线程的,则管道的同步接口允许您在处理 N 个客户端应用程序线程时使用单个连接。 (所以在这里,它是一种帮助建立线程安全连接的实现策略。)

      如果管道接口是异步的,那么即使是单线程客户端应用程序也可以受益。吞吐量至少增加了一个数量级。

      (流水线注意事项:编写容错流水线客户端并非易事。)

      理想情况下,我应该使用图表,但请注意剪辑结尾处发生的情况: http://www.youtube.com/watch?v=NeK5ZjtpO-M

      【讨论】:

      • 感谢您的详细解释。但是,我的问题主要是指如何将此功能专门用于 Booksleeve Redis 客户端(如果可能),而不是一般如何实现。
      • 我正在解决“关于 Redis 事务和管道之间的区别有点混淆”。至于 Booksleeve(不知道),这可能是一个好的开始:code.google.com/p/booksleeve/source/browse/Async/…
      • @alphazero 实际上,该异步项目只是将 C# 5 async 语言功能与 BookSleeve 结合使用的一个说明。 BookSleeve 中的一切都是异步的和流水线的。
      【解决方案3】:

      这里是Redis Transactions Documentation的链接

      关于 BookSleeve,请参考 Marc 的this post

      “CreateTransaction() 创建一个暂存区域来构建命令(使用完全相同的 API)并捕获未来的结果。然后,当调用 Execute() 时,缓冲的命令被组合成一个 MULTI/EXEC 单元并在一个连续块(显然,多路复用器会将所有这些一起发送)。”

      如果您在事务中创建命令,它们将自动“流水线化”。

      【讨论】:

      • 但是,这里的“事务”和“流水线”还是有区别的,前者是redis支持的正式特性,后者只是客户端发送多个(单独)的能力一起请求。我问的是后者,因为我不需要原子性,而 Booksleeve 被称为"pipelined .NET bindings for redis"。不过感谢您的回答,这是我目前正在使用的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-04
      • 2017-01-09
      • 2017-03-24
      • 2011-07-04
      • 2015-05-18
      • 2019-11-07
      • 1970-01-01
      相关资源
      最近更新 更多