【问题标题】:Proper activerecord connection pool size with sidekiq and postgres for multiple sidekiq processes?用于多个sidekiq进程的sidekiq和postgres的正确activerecord连接池大小?
【发布时间】:2015-01-09 01:52:36
【问题描述】:

我正在运行 7 个 sidekiq 进程(货币设置为 40)和一个乘客网络服务器,连接到一个 postgres 数据库。 Rails pool 设置为 100,而 postgres max_connections 设置也是默认的 100。

我刚刚添加了一个新的作业类,其中每个作业都发出多个 postgres 请求,我开始在许多 sidekiq 作业上出现此错误,有时在我的网络服务器上:PG::ConnectionBad: FATAL: remaining connection slots are reserved for non-replication superuser connections

我尝试将 postgres max_connections 增加到 200,但仍然出现错误。然后我尝试将 activerecord 池设置减少到 25(每个进程 25 个连接 = 200 个总连接),我想我可能会开始收到 DB 连接超时错误,但至少它会停止“没有剩余连接插槽”错误。

但我仍然收到 remaining connection slots are reserved 错误。

处理这个问题的更聪明的方法可能是将我不断重复使用的重要 postgres 数据加载到 redis 中,然后从 redis 访问它 - 这显然与 sidekiq 一起玩得更好更快。但即使我这样做了,我也想了解这里的 postgres 连接发生了什么:

  • 我可能会泄漏连接吗,我应该这样做吗? 在 sidekiq 工作中进行管理?

(见Releasing ActiveRecord connection before the end of a Sidekiq job

  • 我是否应该研究更模糊的问题,例如锁定/争用问题 还是 PG 驱动程序的线程问题?

(请参阅https://github.com/mperham/sidekiq/issues/594。我认为我使用 ActiveRecord 非常简单,对于 Rails 应用程序没有太多晦涩或异常的逻辑......)

  • 或者我只是不明白 ActiveRecord 池的设置 和 postgres max_connection 设置一起工作...?

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord sidekiq


    【解决方案1】:

    我的情况可能过于具体,无法帮助许多其他遇到此错误的人,但我会分享我发现的内容,以帮助您指出正确的方向。

    我可能会泄漏连接吗?我应该在 sidekiq 作业中管理这些吗?

    不,不太可能。 Sidekiq 的默认中间件包括a hook to close connections,即使作业失败。我花了很长时间才明白这到底是什么意思,所以如果你不确定这意味着什么,tl;dr:如果你正常使用 Sidekiq,它不会泄漏连接

    我是否应该研究一些更晦涩的问题,例如锁定/争用问题或 PG 驱动程序的线程问题?

    除非您使用非常晦涩的设置,否则它可能会更简单。

    或者我只是不明白 ActiveRecord 池设置和 postgres max_connection 设置如何协同工作...?

    如果我错了,任何人都可以随时纠正我,但这里是我正在针对池设置、max_connections 和 sidekiq 进程进行的指导:

    最小 DB 池大小 = sidekiq 并发设置

    最大数据库池大小* = postgres max_connections / 总 sidekiq 进程(+ 为 Web 进程保留一些连接)

    *请注意,活动记录只会在新线程需要一个新连接时创建一个新连接,所以如果你的 95% 的线程不同时使用 postgres,你应该能够使用比它少得多的 max_connections如果每个线程都试图同时检查一个连接。

    什么解决了我的问题:

    在我的 Ubuntu 机器上,我已将 vm.overcommit_memory 设置更改为 1 as recommended by redis,以便它可以在不破坏机器的情况下生成写入磁盘进程。

    这是正确的方法,但如果内存使用率过高,postgres 很容易被 OOM (out of memory) Killer 杀死。事实证明,如果 postgres 收到来自 OOM Killer 的终止信号,它将停止允许新连接。

    重新启动 postgres 后,sidekiq 能够再次连接。长期的解决方案是简单地处理内存泄漏并确保内存使用率不会太高。此外,还可以将 OOM 杀手配置为在杀死 postgres 之前优先杀死我的 sidekiqs。

    【讨论】:

      猜你喜欢
      • 2014-10-02
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-05
      • 2014-04-19
      • 1970-01-01
      相关资源
      最近更新 更多