如何在akka-streams map中使用异步驱动程序vs mapAsync

时间:2016-11-22 10:01:06

标签: scala couchbase akka-stream

我刚开始使用reactivecouchbase异步数据库驱动程序,但遇到了一些基本的设计问题。 在传统的approch中,我会通过限制与数据库的连接数来限制我对数据库施加的压力。但是使用异步驱动程序,我可以使用新查询来淹没数据库吗?

这已经变得很重要的例子如下。

假设我有两种不同的方式来调用数据库。

我的函数调用DB:

asyncCallDB: Future[DBResponse]
blockingCallDB: DBResponse

现在我想通过一个流来映射db调用,我可以使用两个不同的函数:

Flow.map()
Flow.mapAsync(numberOfConcurrentCalls)()

现在我的问题是你如何选择调用数据库:

Flow.map(blockingCallDB) //One call at a time with back preassure
Flow.map(asyncCallDB) //Unlimited calls floods db no back pressure?

Flow.mapAsync(numberOfConcurrentCalls)(blockingCallDB) //Up to numberOfConcurrentCalls at the same time with back pressure
Flow.mapAsync(numberOfConcurrentCalls)(asyncCallDB) //Unlimited calls floods db no back pressure?

我觉得我在这里缺乏理解,并且想要了解这种类型的决定。

1 个答案:

答案 0 :(得分:3)

ReactiveCouchbase使用AsyncHttpClient与Couchbase服务器进行通信。你可以see in the source code调用setMaximumConnectionsTotal,这会限制并发连接的数量。实际值取决于您在couchbase.http.maxTotalConnections中配置的内容。

您创建的每个AsyncHttpClient都有一个CouchbaseBucket。因此,每个maxTotalConnections最多只有CouchbaseBucket个连接。

来自Couchbase documentation on N1QL REST API

  

REST API运行同步,因此一旦执行了语句   请求启动后,结果将流式传输回客户端,   在声明的执行完成时终止。

因此,在实践中,每个存储桶的并发查询数限制为maxTotalConnections

因此,DB上的背压总是以某种方式受到限制。要么是因为您将maxTotalConnections设置为非负数,要么是因为RAM或文件描述符数量有限而无法创建更多连接。

但是,仍然可能会创建太多Future s,因此您的客户端将耗尽内存。每当您认为可能出现这种情况时,您应该使用mapAsync,如in this answer所述,或"Buffers and working with rate" (Akka documentation)中提到的其他技术之一。

good description of mapAsync in the Akka documentation

  

将传入元素传递给返回Future结果的函数。 :当   未来到来的结果是通过下游。最多可同时处理n个元素 ...

请注意,Flow.mapAsync不会自行运行任何内容,只会返回Flow,您必须在SourceSink之间进行连接,然后runAkka Quick Start Guide以一种非常易于理解的方式描述了这一点。