34

我想知道 Rails database.yml 中的以下设置:

默认情况下,ActiveRecord 的连接池的数据库连接数设置为 5:

development:
  ...
  pool: 5

但默认情况下,Rails 3 是单线程的。为什么默认需要 5 个连接?

据我了解,单线程 Rails 应用程序不能一次触发多个数据库操作,为什么需要保持更多连接打开?

我会假设 2 个连接是有意义的,所以即使另一个超时,你也总是有一个活动连接,但保持五个连接对我来说似乎有点奇怪。

我错过了什么吗?

更新如果其他人很好奇,我刚刚找到了一个解释它的提交: https ://github.com/rails/rails/commit/b700153507b7d539a57a6e3bcf03c84776795051

事实上,这些默认设置没有任何意义,它已被修复,但由于测试套件而暂时恢复(一年前)。

4

2 回答 2

18

在这里聚会已经很晚了,但是我今天在生产中用完了数据库连接。

像很多人一样,我使用 Sidekiq 来执行异步工作,例如发送电子邮件。重要的是要注意 Sidekiq 作为多线程进程运行。

所以,我不只是有一个单线程 Rails 应用程序,因此这个答案并不直接适用于所提出的问题,但我认为值得在这里说些什么,因为我认为现在多线程 Rails 应用程序相对正常。

这意味着您需要调整池大小,以便创建足够的连接来处理所有可以排队并花费超过 5 秒的作业(在引发错误之前等待数据库连接的默认超时时间)。

于 2015-05-14T05:44:09.607 回答
7

管理连接

对于像 Mongrel/Passenger/etc 这样的单线程服务器,连接池的主要好处是连接是在 Rails 请求处理之外的 Rack 处理程序中建立/维护的。这允许建立一次连接而不是多次建立连接,因为它以不同的方式使用。目标是重用已建立的连接并最小化连接数。这应该防止必须在给定的请求处理周期内重新连接,甚至可能在请求之间重新连接(如果我没记错的话)。

多个并发连接

尽管大多数用例(Mongrel/Passenger)都是单线程的,并且一次只能使用一个连接——但 JRuby 和环境/应用程序服务器具有完整的多线程支持。Rails 从 2.2 开始就是线程安全的

  • 连接池在 ActiveRecord 内部处理,因此所有应用程序服务器的行为应该基本相同。

  • 数据库连接池一开始是空的,并根据需要随着时间的推移创建连接。此池的最大大小默认为 5,并在 database.yml 中进行配置。

  • 请求和用户共享来自该池的连接。请求在第一次需要访问数据库时检查连接,然后在请求结束时重新检查连接。

  • 如果你使用 Rails.threadsafe!模式,那么多个线程可能同时访问多个连接,因此根据请求负载,您可能有多个线程竞争几个连接。

如果您使用的是单线程应用程序,您可以相应地进行更改。根据大多数用户的需要,默认值为 5,因为现在一天拥有一个多线程应用程序是正常的。

于 2013-02-28T09:51:35.457 回答