我刚开始使用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?
我觉得我在这里缺乏理解,并且想要了解这种类型的决定。
答案 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
,您必须在Source
和Sink
之间进行连接,然后run
。 Akka Quick Start Guide以一种非常易于理解的方式描述了这一点。