正确设置单线程Rails应用程序的数据库连接池database.yml

时间:2013-02-26 10:37:05

标签: ruby-on-rails database postgresql activerecord

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

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

development:
  ...
  pool: 5

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

据我所知,单线程Rails应用程序不能同时触发多个数据库操作,为什么还需要保持更多连接打开?

我认为2个连接是有意义的,所以你总是有一个活动连接,即使另一个连接超时,但是对我来说看起来有点奇怪。

我错过了什么吗?

UPDATE 如果其他人好奇,我只是发现了一个解释它的提交: https://github.com/rails/rails/commit/b700153507b7d539a57a6e3bcf03c84776795051

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

2 个答案:

答案 0 :(得分:18)

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

与很多人一样,我使用Sidekiq来执行异步工作,例如发送电子邮件。值得注意的是,Sidekiq是一个多线程进程。

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

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

答案 1 :(得分:7)

管理连接

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

多个并发连接

虽然大多数用例(Mongrel / Passenger)都是单线程的,并且一次只能使用一个连接 - 但JRuby和环境/应用服务器都具有完整的多线程支持。自2.2以来,Rails一直是线程安全的。

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

  • 数据库连接池为空,并根据需要随时间创建连接。此池的最大大小默认为5,并在database.yml中配置。

  • 请求和用户共享此池中的连接。请求在第一次访问数据库时检出连接,然后在请求结束时检查连接。

  • 如果你使用Rails.threadsafe!模式,然后多个线程可能 同时访问多个连接,因此取决于 请求加载你可能有多个线程争夺一些 连接。

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