django の connection pooling について 調べてみました。


普段、仕事では java WEB アプリケーション を触っており、DB の コネクションプール についてたまに意識をすることがあります。
ふと、django で connection pooling を意識したことがなかったので、django での connection pooling について調べてみました。


前提

  • django の version

    pip list | grep Django
    -----------------------------------------
    Django (1.10.7)
    -----------------------------------------
    

  • Database
    自分が使っているのが、postgress なので基本的に postgress の話 になります。


参考


Java の APサーバーにおける connection pooling について

WAS虎の巻: 第3回「JDBCとデータベース接続」 WAS の JDBC のコネクションプーリングの説明が記載されています。2.データベース接続構成 を読むと、どんな機能なのかは把握できるかと思います。
基本的に、パラメータ名等は違うかもしれませんが、Weblogic、Tomcat、Glassfish 等でできることに大きな違いはありません。
確か例外ハンドリングとかで、ベンダーによっては独自の拡張ポイントがあったりした気がします。


django 本体に connection pool の実装があるか?

django 本体には、connection pool の実装はありません。
CONN_MAX_AGE という値は設定できますが、Django 1.6 がリリースされました | djangoproject.jp に記載がある通り、connection pool しているわけではありません。
Databases | Django documentation | Django を読む限り、CONN_MAX_AGE を 設定すると以下のような挙動となります。

  • default値は、00 の場合、各要求で connection を取得、要求の終わりで、connection を終了する。1
    [1] 動作確認をしてはないです..ドキュメントを読む限りはそういう動作です。

  • 0 以上の値を設定すると、設定回数は connection を保持し、設定回数を超えた場合、または使用できなくなった場合、connection を終了する。

  • CONN_MAX_AGE = None を設定すると、無制限に connection を保持する。

  • 運用時は、CONN_MAX_AGE の connection の持続時間が、 DB側の アイドル状態の connection の timeout 時間 を 超えないように設定する。2
    [2] 超えると、DB接続エラーの後に connection が復旧するので、運の悪い ユーザに 1度はDBエラーが発生します。


django の connection プールの選択肢

django 1.7 and connection pooling to PostgreSQL? - Stack Overflow を見る限り、以下の選択肢があります。3

  • django-postgrespool を使う

  • PgBouncer を使う
    それぞれ以下に記載します。

[3] CONN_MAX_AGE のことも記載がありますが、上で書きましたので、除外します。

django-postgrespool を使う

[kennethreitz/django-postgrespool: Postgres Connection Pooling for Django, powered by SQLAlchemy.
] は、connection pooling 機能を提供する django-plugin です。

Webシステムにおけるデータベース接続アーキテクチャ概論 - ゆううきブログ に記載のある コネクションプーリング: ドライバ型 の実装になります。

内部で SQLAlchemy の pooling 機能を使っており、

# DATABASE_POOL_ARGS should be something like:
# {'max_overflow':10, 'pool_size':5, 'recycle':300}
pool_args = getattr(settings, POOL_SETTINGS, {})
db_pool = manage(Database, **pool_args)
で、SQLAlchemymanage メソッドを使って、pool を生成しており、デフォルトの QueuePool を使いそうに思います。
QueuePool には以下のプロパティの設定が可能です。
QueuePool は、Pool を継承しているので、Pool で保持する設定値も設定可能です。

  • pool_size
    最小 connection 数の指定

  • max_overflow
    pool_size を超えて許容する connection 数の指定
    1つのAPサーバーあたり、最大で、pool_size + max_overflow のコネクションを生成

  • recycle
    コネクションの再利用期間値、期間を超えると、接続を閉じて、再生成する。
    秒数指定 -1 を指定すると、保持し続ける? か、再利用しない?

  • timeout
    コネクションの取得を待つ時間、default 30秒。

use_threadlocalreset_on_returnpre_ping 等 重要そうな設定なので、Connection Pooling — SQLAlchemy 1.2 Documentation を一通り読んでおいたほうがいいかと思います。

Java の connection pooling に近い設定ができるように思いました。

PgBouncer を使う

Webシステムにおけるデータベース接続アーキテクチャ概論 - ゆううきブログ に記載のある コネクションプーリング: ドライバ型 の実装になります。
上記記事にしっかり記載されていて、特にここで書くことはありません。
2回書きますが、特にここで書くことはありません。


psycopg2 にもコネクションプーリングの機能がある

【PostgreSQL】psycopg2のコネクションプーリングを使ってみよう | アシスト に記載されていますが、psycopg2 自体にも、コネクションプーリングの機能があるようです。
機能的には、SQLAlchemy の pool のほうが多機能で、記事にもある通り、maxconnmixconn 以外の設定をしたい場合は、自前で拡張していくことになりそうです。


個人ブログにおいて、connection プール を使う使わないの判断

個人ブログにおいて、connection プール 使うか使わないについてですが、以下の2点より不要かなと思いました。

  • Memcache で 記事は chache しているので、ほとんどDBアクセスが発生しない。

  • ログインユーザーは cahce を 使用していないが、cache を使用しないのは基本的に、私ただ一人。

ユーザーがログインして更新系の操作が多いサイト、又は、DB cahce を使ってる場合は、 ブログ等参照系が多いサイトでも使ったほうがいいかと。

以上です。

コメント