(Heroku + Sidekiq) 我对连接池工作原理的理解是否正确?

use*_*003 6 postgresql ruby-on-rails heroku sidekiq puma

假设我在 Heroku + Rails 上有以下设置,有一个 web dyno 和两个 worker dyno。

以下是我认为是真实的,我希望有人能证实这些陈述或指出一个不正确的假设。

我对其中的大部分内容充满信心,但我对客户端和服务器的使用感到有些困惑,“连接池”指的是 DB 和 Redis 连接,而“工人”指的是 puma 和 heroku dyno 工人。

我想说得非常清楚,我希望这也可以作为任何其他有此问题的初学者的综合指南

谢谢!

在此处输入图片说明

一切如何相互作用

  • 一个 web dyno(运行 Rails 应用程序的地方)

    • 仅在需要查询数据库以提供页面请求时才与数据库交互
    • 仅在将作业推送到 Sidekiq 队列(存储在 Redis 中)时才与 Redis 交互。它是 Sidekiq客户端
  • 工人动态

    • 仅当它运行的 Sidekiq 作业需要查询数据库时才与数据库交互
    • 仅与 Redis 交互以从 Sidekiq 队列(存储在 Redis 中)中提取作业。它是 Sidekiq服务器

ActiveRecord 池大小

  • 25 的 ActiveRecord 池大小意味着每个 dyno有 25 个连接可以使用。(这是我最不确定的。是每个 dyno 还是每个 Puma/Sidekiq 工人?

  • 对于 web dynos,它一次只能运行 10 个事物(线程)(2 puma x 5 个线程),所以它最多只能消耗 10 个线程。25 超出了它的需要。

  • 对于 worker dynos,Sidekiq 并发为 15 意味着一次可以运行 15 个 Sidekiq 进程。同样,25 个连接超出了它的需要,但它是一个很好的缓冲,以防有无法清除的陈旧或死连接。

  • 总的来说,我的 Postgres DB 可以预期来自 Web dyno 的 10 个连接和来自每个 worker dyno 的 15 个连接,总共最多 40 个连接。

Redis 池大小

  • Web dyno(Sidekiq 客户端)将使用块中size指定的连接池Sidekiq.configure_client。通常 ~3 就足够了,因为客户端不会不断向队列添加作业。(是每个测功机 3 个,还是每个 Puma 工人 3 个?

  • 每个 worker dyno(Sidekiq 服务器)将使用块中size指定的连接池Sidekiq.configure_server。默认是sidekiq并发+2,所以这里每个dyno会占用17个redis连接

小智 2

我不了解 Heroku + Rails,但相信我可以回答一些更通用的问题。

从客户端的角度来看,任何连接的建立/拆除都是非常昂贵的。连接池的概念是拥有一组保持活动状态并且可以在一段时间内使用的连接。JDK HttpUrlConnection 执行相同的操作(假设 HTTP 1.1),因此 - 假设您要访问同一服务器 - HTTP 连接保持打开状态,等待下一个预期请求。同样的事情也适用于此 - 不是每次关闭 JDBC 连接,而是保持连接 - 假设相同的服务器和身份验证凭据 - 因此下一个请求会跳过不必要的工作,并可以立即继续将工作发送到数据库服务器。

有很多方法可以维护客户端连接池,它可能是 JDBC 驱动程序本身的一部分,您可能需要使用 Apache Commons Pooling 之类的东西来实现池化,但无论您做什么,它都会增加您的行为并减少错误这可能是由网络故障引起的,网络故障可能会阻止您的客户端连接到服务器。

在服务器端,大多数数据库提供程序都配置有数据库服务器可以接受的 n 个可能连接的池。通常每个附加连接都有一个占用空间 - 通常非常小 - 因此根据可用内存,您可以计算出可用连接的最大数量。

在大多数情况下,您会希望拥有比预期更大的可用连接。例如,在 postgres 中,配置的连接池大小适用于该服务器上任何数据库的所有连接。如果您的开发、测试和生产都指向同一数据库服务器(显然是不同的数据库),则测试使用的连接可能会阻止生产请求的完成。最好不要小气。