mssql-django におけるコネクション プーリング

この記事では、 mssql-django での接続プールのしくみと、それを Django アプリケーション用に構成する方法について説明します。

接続プールのしくみ

既定では、 mssql-django は pyodbc の組み込みの接続プールを使用します。 接続が Django によって閉じられると、pyodbc は基になる ODBC 接続を閉じるのではなく、それをプールに返します。 後続の接続要求では、プールされた接続が再利用されるため、新しいデータベース接続を確立するオーバーヘッドが軽減されます。

接続プールの設定

接続プールは、 DATABASE_CONNECTION_POOLING 設定によって制御されます。この設定は、 settings.py ( DATABASES ディクショナリの外部) のモジュール レベルに配置されます。

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

# Set to False to disable pyodbc's connection pooling
DATABASE_CONNECTION_POOLING = False
価値 Behavior
True (既定値) 接続プーリングが有効になっています。 閉じられた接続はプールに返されます。
False 接続プーリングが無効になっています。 各接続は、解放されると完全に閉じられます。

接続プールを無効にするタイミング

次のシナリオでは、接続プールを無効にすることを検討してください。

  • トークンベースの認証: 有効期限が切れたアクセス トークンを使用すると、プールされた接続に古いトークンが保持される可能性があります。
  • 接続の問題のデバッグ: プールを無効にすると、各要求で新しい接続が作成され、トラブルシューティングが簡単になります。
  • 有効期間の短いプロセス: いくつかのクエリを実行して終了するスクリプトまたは管理コマンドの場合、プールにはメリットはありません。

接続の再試行の設定

プール設定に関係なく、失敗した接続試行の再試行動作を構成できます。 再試行とタイムアウトのオプションの完全な一覧については、「 構成リファレンス」を参照してください

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "connection_retries": 3,
            "connection_retry_backoff_time": 10,
            "connection_timeout": 30,
        },
    },
}

Django のCONN_MAX_AGE

Django には、Django を閉じる前にデータベース接続を開いたままにする期間を制御する CONN_MAX_AGE 設定も用意されています。 この設定は、pyodbc の接続プールと共に機能します。

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "CONN_MAX_AGE": 600,  # Keep connections open for 10 minutes
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

CONN_MAX_AGEの詳細については、Django データベース設定のドキュメントを参照してください

実用的な出発点:

  • CONN_MAX_AGE=0: デバッグと有効期間の短いジョブで最も安全です。
  • CONN_MAX_AGE=600: 多くの Web アプリに適した既定値です。
  • CONN_MAX_AGE=3600: ロード テスト後の安定した高スループット サービスに適しています。

Note

ASGI サーバー (Daphne や Uvicorn など) またはスレッド展開を使用する場合、永続的な接続が非同期コンテキスト間でリークする可能性があります。 ASGI サーバーで CONN_MAX_AGE を使用する場合は、 CONN_HEALTH_CHECKS = True (Django 4.1 以降) を設定し、現実的なコンカレンシーでテストします。 詳細については、 接続管理に関する Django のドキュメントを参照してください。

CONN_HEALTH_CHECKS は、再利用前にコネクションプール内の接続を検証します。 Django が古い接続を検出すると、透過的に新しい接続が開きます。 これにより、要求ごとのチェック コストが少なく、通常は有効期間の長いプロセスに対して有効にする価値があります。