【问题标题】:How to prevent "Mysql2::Error: This connection is in use by" with Sidekiq如何使用 Sidekiq 防止“Mysql2::Error: This connection is in use by”
【发布时间】:2014-03-31 23:09:28
【问题描述】:

在运行 Sidekiq 几个小时后,我看到一堆作业以 Mysql2::Error: This connection is in use by: #<Celluloid::Thread:0x0000000d1b56e0 sleep> 失败。似乎 Sidekiq 线程在 MySQL 连接池上存在某种冲突。

concurrency 在 sidekiq.yml 中设置为默认 25,在 database.yml 中池为 28。没有长期存在的查询,异常发生在标准的 finder 调用中,没什么特别的。

如何防止此错误以确保作业顺利运行?

【问题讨论】:

  • 您使用的是什么服务器?独角兽?这是在开发或生产中发生的吗?
  • 它是一个独立的 Sidekiq 处理器服务器。是的,生产。
  • 您是否仅将此数据库用于此工作人员?因为如果您将同一个数据库用于另一个进程,您需要查看您的数据库获得了多少连接
  • 不,它也被 Rails 应用服务器使用(工作正常),但我假设错误是在谈论 Sidekiq 进程中的另一个线程。

标签: mysql multithreading ruby-on-rails-4 database-connection sidekiq


【解决方案1】:

您的问题是因为 sidekiq 正在获取到您的数据库的所有连接,同时 rails 应用程序也在请求连接。

您有 25 个 sidekiq 工作人员,但您有多少个 Rails 服务器?

例如如果你有独角兽运行 4 个童工,你将需要 29 个插槽(至少)

【讨论】:

  • database.yml 池变量反映了每个进程的连接数,因此每个 Unicorn 在这里也有 28 个连接。 (实际上他们只需要 1,但实际上这不是问题,因为他们不会使用更多并且不会长寿。)由于 Unicorns 没有任何 DB 问题,这不是因为与他们争用。 (它们也在不同的机器上。)
  • 但是它们共享同一个数据库,它们在哪台机器上并不重要,并且池不是每个进程是每个数据库
  • 假设我有 4 只独角兽。这意味着实际上有(最多)125 个连接。不是 28 岁。
  • 4 个独角兽 + 25 个 sidekiq = 29 个用于数据库池的插槽,它们是数据库的插槽,而不是每个进程的插槽
  • 池变量表示每个进程有多少个连接,这里有5个进程,所以有125个可能的连接。 (28 是任意的,可能是 25,但我留下了一些多余的东西,以防出现竞争情况,github.com/mperham/sidekiq/issues/503 有一些提示,它应该是处理器数量的 1.5 倍,尽管理论上应该是相同。)
【解决方案2】:

最后通过隔离所有工人解决了这个问题。它归结为 Typhoeus 库显然不是线程安全的。替换为 Net/HTTP,它又可以工作了。

更多详情请访问https://github.com/mperham/sidekiq/issues/1400#issuecomment-45838886

【讨论】:

    【解决方案3】:

    在我们的案例中,我们在特定的工作人员类型中遇到了很多此类错误。我们发现我们在这些工作程序中运行的一项作业中使用了 Timeout.timeout() 调用。我们删除了这些调用,之后这些错误就消失了。有关 Timeout.timeout() 调用为何危险的参考,请查看 herehere

    【讨论】:

      猜你喜欢
      • 2012-01-18
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 2016-05-12
      • 2013-01-14
      相关资源
      最近更新 更多