Jos*_*osh 4 postgresql activerecord ruby-on-rails sidekiq
我正在运行7个sidekiq进程(货币设置为40)以及一个乘客网络服务器,连接到postgres数据库.Rails池设置设置为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错误.
处理这个问题的更聪明的方法可能是加载我不断重用redis的重要postgres数据,然后从redis访问它 - 这可以通过sidekiq更好地和快速地播放.但即使我这样做,我也想通过postgres连接了解这里发生了什么:
(请参阅Sidekiq作业结束前释放ActiveRecord连接)
(请参阅https://github.com/mperham/sidekiq/issues/594.我认为我使用ActiveRecord非常简单,对于rails应用程序没有太多模糊或异常的逻辑......)
我的情况可能过于具体,无法帮助其他许多人遇到此错误,但我会分享我发现的内容,以防它指向正确的方向.
我是否可能泄漏连接,是否应该在sidekiq工作中管理?
不,不太可能.Sidekiq的默认中间件包括一个挂钩,即使作业失败也可以关闭连接.我花了很长时间才明白这意味着什么,所以如果你不确定这意味着什么,那么:如果你正常使用它,那么Sidekiq不会泄漏连接.
我是否应该研究更加模糊的事情,比如锁定/争用问题或PG驱动程序的线程问题?
除非你使用一个非常模糊的设置,否则它可能更简单.
或者我可能只是不了解ActiveRecord池设置和postgres max_connection设置如何协同工作......?
如果我错了,任何人都可以随意纠正我,但这是我正在进行的池设置,max_connections和sidekiq进程的指导:
最小数据库池大小= sidekiq并发设置
最大数据库池大小*= postgres max_connections/total sidekiq进程(+为Web进程留下一些连接)
*请注意,当新线程需要一个时,活动记录只会创建一个新连接,所以如果95%的线程不同时使用postgres,那么你应该能够使用比每个线程少得多的max_connections.正在尝试同时检查连接.
什么解决了我的问题:
在我的Ubuntu机器上,我已经按照redis的建议将vm.overcommit_memory设置更改为1 ,这样它就可以在不破坏机器的情况下将其写入磁盘进程.
这是正确的方法,但是如果内存使用率过高,那么就会让OgI(内存不足)被杀死.事实证明,如果从OOM Killer收到一个终止信号,postgres将停止允许新连接.
一旦我重新启动postgres,sidekiq就可以再次连接.长期解决方案只是处理内存泄漏并确保内存使用率不会太高.此外,还可以配置OOM杀手,以便在杀死postgres之前优先杀死我的sidekiqs.
| 归档时间: |
|
| 查看次数: |
2419 次 |
| 最近记录: |