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

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

接続プールのしくみ

デフォルトでは、 mssql-django ドライバーレベルの接続プーリングを使用しています。 デフォルトのpyodbcパスはpyodbcプーリングを使い、mssql-pythonパスはmssql-pythonプーリングを使用しています。 Djangoが接続を閉じると、アクティブなドライバーは基盤となるデータベース接続を閉じる代わりに、その接続をプールに戻します。 後続の接続要求では、プールされた接続が再利用されるため、新しいデータベース接続を確立するオーバーヘッドが軽減されます。 ドライバー選択の詳細については、「 ms sql-djangoのデータベースドライバー選択」をご覧ください。

接続プールの設定

接続プールは、 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 driver-level connection pooling
DATABASE_CONNECTION_POOLING = False
価値 Behavior
True (既定値) 接続プーリングが有効になっています。 閉じられた接続はプールに返されます。
False ドライバーレベルの接続プーリングは無効にされています。 pyodbc パスは Database.pooling=False を設定し、mssql-python パスは PoolingManager.disable() を呼び出します。

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

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

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

接続の再試行の設定

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

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 設定も用意されています。 この設定はドライバーレベルの接続プーリングと連動して動作します:

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 を使う場合は、サポートされているDjangoバージョンで CONN_HEALTH_CHECKS = True を設定し、現実的な並行性でテストしてください。 詳細については、 接続管理に関する Django のドキュメントを参照してください。

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