エラー

Railsでsidekiq使ってるときに以下のエラーが出ました。

could not obtain a database connection within 5.000 seconds

これは、使用可能なコネクション数よりも多くの接続を使用しようとすると、コネクションに空きがでるまで待機状態になります。 一定の時間待機してもコネクションが取得できない場合は上記のようにタイムアウトエラーが発生します。

sidkiqで実行した処理

  • 全ユーザーに対して追加でユーザー情報を含んだ画像を生成する
  • 生成した画像のパスをユーザーデータに追加し保存する
  • 画像生成処理は1-2秒かかる

設定確認

  • sidekiq concurrency: 10
  • db pool: 5

ログ確認

sidekiq-log

同時実行は5件ずつになっている。

推測

concurrrencyは10だがコネクション数が5なので5件の処理が常に待機状態になっている。 ユーザー全体に対して実行したため徐々にCPU負荷が上がっていき、画像生成処理の処理が遅くなり5秒を超えても終わらなくなった。 待機していた処理が5秒超えたので上記のエラーが発生した。

対策

concurrencyを5に変更した

今回のsikiq処理は一回限りのものなので単純にdb pool数に合わせることで乗り切れると考えたのでこの対策にしました。後で元に戻すかもしれません。

むしろ一時的に変更する方が良かったかもしれませんが、今の所バックグラウンド処理にシビアなパフォーマンスを求める処理を持たせてないので一旦コレで良いかなと思っています。

以上です。

参考

https://guides.rubyonrails.org/v5.1/configuring.html#database-pooling