【问题标题】:How do I manage connection pooling to PostgreSQL from sidekiq?如何管理从 sidekiq 到 PostgreSQL 的连接池?
【发布时间】:2016-07-05 22:14:39
【问题描述】:

问题 我有一个运行几百个sidekiq 后台进程的rails 应用程序。它们都连接到一个 PostgreSQL 数据库,该数据库对提供 250 个连接并不十分满意——它可以,但如果所有 sidekiq 进程不小心将查询发送到数据库,它就会崩溃。

选项 1 我一直在考虑在数据库前面添加 pgBouncer,但是我目前无法使用它的事务模式,因为我高度依赖于在开头设置 search_path每个作业处理,用于确定要处理哪个“国家”(PostgreSQL 模式)(公寓宝石)。在这种情况下,我将不得不使用基于会话的连接池模式。然而,据我所知,这将要求我在每次作业处理后断开连接,将连接释放回池中,这将是非常昂贵的性能,不是吗?我错过了什么吗?

选项 2 使用基于应用层的连接池当然也是一个选项,但是我不确定如何使用 sidekiq 为 PostgreSQL 做到这一点?

选项 3 是我没想到的?

【问题讨论】:

    标签: postgresql connection-pooling sidekiq pgbouncer apartment-gem


    【解决方案1】:

    选项 1:您是对的,会话需要您断开并重新连接,这会增加开销。成本有多高取决于访问模式,即连接/tcp 握手等占完成的总工作的比例以及您需要什么样的延迟。绝对值得进行基准测试,但如果连接是短暂的,那么开销将非常明显。

    选项 2/3:您可以对 sidekiq 作业进行速率限制或节流。这里有几个项目正在解决这个问题......

    队列限制

    • Sidekiq Limit Fetch:限制能够同时运行指定队列的工作人员数量。您可以暂停队列并动态调整队列分布的大小。还跟踪每个队列的活动工作人员数量。支持全局模式(多个 sidekiq 进程)。还有一个额外的阻塞队列模式。
    • Sidekiq Throttler: Sidekiq::Throttler 是 Sidekiq 的中间件,它增加了基于每个工作人员对作业执行进行速率限制的能力。
    • sidekiq-rate-limiter:Redis 支持,作业处理的每个工作人员速率限制。
    • Sidekiq::Throttled:并发和阈值限制。

    我从这里得到了以上内容

    https://github.com/mperham/sidekiq/wiki/Related-Projects

    如果您的应用程序必须为每个进程建立一个连接,并且您无法在更多线程可以使用连接的情况下将其分解,那么它就是 pgBouncer 或基于应用程序的连接池。连接池实际上会以某种方式限制或限制您的应用程序以保存数据库。

    【讨论】:

    • "如果连接是短暂的,那么开销将非常明显" -> 听起来会很疼,但这里说的是毫秒(取决于 pgBouncer 实例运行的位置 -> 也许可以在应用服务器上运行,跳过网络往返),看看这个:depesz.com/2012/12/02/what-is-the-point-of-bouncing
    【解决方案2】:

    Sidekiq 应该只要求每个工作线程有一个连接。如果您将concurrency 设置为合理的值,例如10-25,我认为您不应该同时使用250 个数据库连接。您正在运行多少个工作进程,它们的并发性是多少?

    此外,您可以在该页面上看到,即使您有高并发设置,您仍然可以创建一个由该进程内的线程共享的连接池。

    【讨论】:

    • 这与我的问题无关。我需要 250 个连接可用,因为我正在运行 20 个进程,每个进程有 10 个线程。
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多