LoginSignup
3
5

More than 5 years have passed since last update.

ActiveRecordのConnection管理

Posted at

4.2.x 系で調査。5.x系でかわっているかもしれない(おえてない)

こんな構成

ActiveRecord::Core <>--- ConnectionHandler <>--- ConnectonPool
       |
       | include
       v
ActiveRecord::Base 

ConnectionHandler

コネクション全般を管理する
ActiveRecord::Core (Module)で定義されてる connection_handler メソッドを使うと取得可能

ConnectionHandlerの取得
ActiveRecord::Base.connection_handler

おもな役割はコネクションプールの管理

  • アプリケーションがもつコネクションプール全体の管理 (active_connections?, clear_all_connections!, connection_pool_list)
  • 個々のコネクションプールの作成 (establish_connection)
  • 個々のコネクションプールの切断 (remove_connection)

個々のコネクションプールは オーナー をもち、通常は establish_connectionを呼んだクラスのselfである。
デフォルトのオーナーは ActiveRecord::Base 

ConnectionPool

個々のコネクションプールは オーナー をもつ
ActiveRecord::BaseのコネクションPoolは、database.ymlにある、
Rails.envで定義された設定を使い接続する。

モデルごとにコネクションプールを作成する

レシーバーがオーナーのコネクションプールを作成する
オーナーがかわることに注意

establish_connection
class Hoge < ActiveRecord::Base
  establish_connection adapter: 'mysql2', host:'localhost', username: 'hgoe', password: 'hogehoge'
end

100クラスで establish_connection を呼ぶと、合計で101個のコネクションプールが作成される。
さらに接続数は101個のコネクションプールのプール数の合計値が上限である。
デフォルト値は 5 なので、最大接続数が505となる可能性がある。

さらに、unicornなどのアプリケーションサーバを使うと、Worker(プロセスxスレッド数)だけ接続される。

接続数を抑制する

通常は、デフォルトの接続以外にコネクションをわけたい場合は、抽象クラスを用意する

class SlaveConnectionModel < ActiveRecord::Base
  self.abstract_class = true
  establish_connection adapter: 'mysql2', host:'localhost', username: 'hgoe', password: 'hogehoge'
end

class Hoge < SlaveConnectionModel; end
class Foo < SlaveConnectionModel; end

参考

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5