【问题标题】:Disabling Connection Pooling in Rails to use PgBouncer在 Rails 中禁用连接池以使用 PgBouncer
【发布时间】:2019-07-27 09:50:54
【问题描述】:

我们有一个访问大型 PostgreSQL 数据库的 Ruby on Rails 4.2.8 项目。我们将使用 PgBouncer 添加一个用于连接池的新服务器。

既然 PgBouncer 将处理数据库连接池,我们是否需要关闭 Rails 自动连接池?我们的 database.yml 中没有配置任何东西,所以我认为使用的是默认值(池)5。

  1. 添加 PgBouncer 是否意味着我们应该关闭 Rails 连接池?
  2. 如果是这样,它是如何工作的,我们是否只需设置 Pool 在 database.yml 中为 0?

谢谢

【问题讨论】:

  • 你们最后做了什么?

标签: ruby-on-rails postgresql pgbouncer


【解决方案1】:

TLDR;不要改变任何东西

rails 中的池化与 PGBouncer 中的池化不同。 rails 连接池是该进程中任何线程可用的一组连接,通常只有 1 个。rails 池中的每个连接都将与您的 postgres 数据库或 PGBouncer(如果它位于 postgres 前面)建立连接。在大型 Rails 应用程序中,您将在每个服务器上运行多个 Rails 进程,并在负载均衡器后面的多个服务器上运行。像这样的:

没有 PGBouncer,每个与 postgres 的连接都会创建一个新的 postgres 进程。在规模上,您需要限制运行的 postgres 进程的数量,这样您就不会最大限度地消耗 CPU 和内存。 PGBouncer 汇集来自所有进程和所有服务器的所有 Rails 池的连接,并在它们之间高效切换。

【讨论】:

  • 有充分的理由禁用连接池,rails 5 不能很好地与 pgbouncer 事务池一起使用,并且 rails 中的连接池使用的长寿命连接,不能很好地与 pgbouncer 会话一起使用池化,因为在会话池中,1 个客户端连接映射到 1 个服务器连接。因此,如果不禁用 rails 连接池以获取短期连接,我们在 rails 中的线程数不能超过我的 postgres 数据库的连接数。
  • @FrederikBaetens 提出了一个非常有效的观点。我们遇到了 PgBouncer 不尊重某些 database.yml 设置(如 statement_timeout)的问题,因为事务池不支持 SET/RESET。你试过这个弗雷德里克吗? (或其他任何人......?)我认为它会在 Rails 应用程序中引入一些延迟,因为它现在需要为每个需要 DB 的请求创建 TCP 连接(假设 PgBouncer 在单独的机器上)。
  • 我还没有考虑设置诸如 statement_timeouts 之类的东西,但要让事务池正常工作,我们所要做的就是disabling advisory locks and disabling prepared statements。 Afaik 事务池不需要每次都建立新的连接。 pgbouncer 和数据库服务器之间的连接是持久的。从您的客户端到 pgbouncer 的连接也是持久的,因为 rails 连接池始终保持与池中 pgbouncer 的连接处于打开状态。
  • 理想情况下,rails 会自己做某种形式的事务或语句池,使用某种数据库参与者,而不是每个线程模型一个连接。
  • 为了将来参考,afaik 无法在 rails 中禁用连接池,尽管有时在没有连接池的情况下为每个请求创建新的短期数据库连接会更方便。但这不是问题,因为 pgbouncer 事务池 + 上面提到的更改设置解决了大多数问题。
猜你喜欢
  • 2020-11-01
  • 2019-12-20
  • 2015-01-06
  • 1970-01-01
  • 2015-12-26
  • 2020-01-16
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
相关资源
最近更新 更多