是否应该在每个Flask请求上建立与Redis群集的连接?

时间:2016-09-13 07:47:59

标签: python flask redis

我有一个Flask API,它连接到Redis群集以进行缓存。我应该在每次烧瓶api电话上创建和拆除Redis连接吗?或者,我应该尝试跨请求维护连接吗?

我反对第二种选择的论点是我应该尽量保持api尽可能无状态,而且我也不知道在请求中保留一些持久性是否会导致线程竞争条件或其他副作用。

但是,如果我想要保持连接,是应该保存在会话上还是应用程序上下文中?

2 个答案:

答案 0 :(得分:2)

这是关于性能和规模。为了让这两个流行语嗡嗡作响,你实际上需要持久的联系。

最终竞争条件与每次请求重新连接没有什么不同,因此不应该成为问题。任何RC都取决于你如何使用redis,但是如果它只是缓存那么就没有多大的错误空间。

我理解客户端POV所需的API无状态,但不太清楚你对服务器端的意思。

我建议你把它们放在应用程序上下文中,而不是会话(那些可能会变得太多),而应用程序上下文为每个进程提供最佳的1个连接(并在启动时立即创建)。这种缩放方式变得简单易用:您永远不必担心在redis盒上达到最大连接数(并且复用越少越好)。

答案 1 :(得分:0)

从性能角度来看,保持与请求之间打开的数据库的连接是一个好主意。原因是打开和关闭连接不是免费的,并且需要一些时间,当您有太多请求时可能会成为问题。数据库只能处理一定数量的连接的另一个问题是,如果打开更多,数据库性能会降低,因此您需要控制同时打开的连接数。

要解决这两个问题,您可以使用连接池。连接池包含许多已打开的数据库连接,并提供对它们的访问。当应该从连接执行数据库操作时应从池中取出。操作完成后,应将连接返回到池中。如果在获取所有连接时请求连接,则调用者必须等待,直到某些连接返回到池中。由于在此处理过程中没有打开新连接(它们都提前打开),这将确保数据库不会因太多并行连接而过载。

如果正确使用了连接池,则只使用一个线程就可以使用单个连接。

尽管连接池具有状态(它应该跟踪当前正在使用的连接),但您的API将是无状态的。这是因为从API的角度来看,无状态"表示:没有API用户可见的状态/副作用。您的服务器可以执行许多操作来更改其内部状态,例如写入日志文件或写入缓存,但由于这不会影响返回哪些数据作为对API调用的回复,因此不会生成此API&#34 ;状态"

您可以看到使用Redis连接池here的一些示例。

关于应该存储的位置,我会使用应用程序上下文,因为它更适合purpose