データベース接続プールの設定は、システムとデータベースとの効率的で安定した接続を確保するための重要なステップです。適切な接続プールの設定により、データベース接続数を効果的に管理し、高並行性による接続枯渇問題を回避するだけでなく、適切なタイムアウト設定により無効な接続をタイムリーにクリーンアップし、システム性能を確保できます。
本記事では、接続プールの基本概念、さまざまな接続プールの比較、選択ガイド、接続プールパラメータの推奨設定、およびJDBC設定における重要なパラメータについて説明します。これにより、開発者がデータベースアクセスを最適化するのに役立ちます。
接続プールの基本概念
データベース接続プールは、データベース接続を管理するための技術です。アプリケーションとデータベースの間に接続プールを構築し、事前に一定数のデータベース接続を作成してメモリ内に保持します。アプリケーションがデータベースにアクセスする必要がある場合、接続プールから直接接続を取得し、使用後は接続プールに返却します。これにより、毎回新しい接続を作成する必要がなくなります。
接続プールの主な利点は以下のとおりです:
- パフォーマンスの向上:接続の頻繁な作成と破棄に伴うオーバヘッドを回避します。
- リソース管理:データベース接続の数を制御し、接続枯渇を防ぎます。
- 接続の再利用:接続の利用率を高め、リソースの無駄遣いを減らします。
- 接続監視:接続状態の監視と統計情報を提供します。
接続プールパラメータ
接続プールには通常、以下のコアパラメータが含まれます:
- 初期接続数:接続プールの初期化時に作成される接続数。
- 最小接続数:接続プール内で維持される最小接続数。
- 最大接続数:接続プール内で許可される最大接続数。
- 接続タイムアウト時間:接続を取得するための最大待機時間。
- アイドルタイムアウト時間:プール内でアイドル状態の接続が保持できる最大時間。この時間を超えると回収されます。
- 検出間隔:アイドル接続をチェックする間隔時間。
- 検出クエリ:接続が有効かどうかを検出するために使用されるSQLクエリ。
接続プール設定の推奨事項
マネジメントコンソールの日常的な最小接続数は2つを維持するのが適切です。具体的な数値は、業務の同時実行数やトランザクション処理時間に応じて調整してください。
接続のアイドルタイムアウト時間を設定します。30分を推奨します。
MySQLのデフォルトでは、接続は8時間ごとに自動的に切断されますが、クライアント側ではこの切断を検知できません。そのため、ダーティーコネクションが存在する可能性があります。接続プールは、ハートビートやtestOnBorrowなどのメカニズムを用いて接続の生存状態を確認し、この時間内に接続が使用されない場合は直接切断します。
JDBC設定パラメータ
JDBCはJavaからデータベースに接続するためのインターフェースです。OceanBaseはJDBCドライバを提供しており、JavaアプリケーションからOceanBaseデータベースへの接続をサポートしています。JDBCドライバのダウンロードURLは以下のとおりです:OceanBase JDBCドライバ。
JDBCでは重要なパラメータがいくつかあり、必ず設定する必要があります。これらはすべて、接続プールのConnectionPropertiesまたはJdbcUrlで設定できます。具体的なパラメータとその説明は以下の表のとおりです。
パラメータ |
説明 |
|---|---|
| socketTimeout | ネットワークソケットのタイムアウト時間をミリ秒単位で定義します。値が0の場合、タイムアウト制限はありません。システム変数 max_statement_time を設定することでもクエリ時間を制限できます。デフォルト値:0(標準設定)。 |
| connectTimeout | 接続タイムアウト値をミリ秒単位で指定します。値が0の場合、タイムアウト制限はありません。デフォルト値:30000。 |
JDBC設定例
本記事では、JDBC設定の例を紹介します。
JDBCを使用してデータベースに接続する際には、データベースのパフォーマンスを最適化するために関連パラメータを設定する必要があります。ここでは、関連するパラメータの設定例をいくつか推奨します。
JDBC接続の例は以下のとおりです:
conn=jdbc:oceanbase://xxx.xxx.xxx.xxx:3306/test?rewriteBatchedStatements=TRUE&allowMultiQueries=TRUE&useLocalSessionState=TRUE&useUnicode=TRUE&characterEncoding=utf-8&socketTimeout=10000&connectTimeout=30000
この接続において、関わる設定パラメータは以下のとおりです:
rewriteBatchedStatements:TRUEに設定することを推奨します。OceanBaseのJDBCドライバーはデフォルトでexecuteBatch()ステートメントを無視し、一括実行されるSQLステートメントのセットを分解して、一つずつデータベースに送信します。この場合、バッチ挿入は実際には単一挿入となり、パフォーマンスが低下します。実際にバッチ挿入を実行するには、このパラメータをTRUEに設定する必要があります。そうすることで、ドライバーはSQLを一括実行します。addBatchメソッドを使用して、同一テーブル上の複数のINSERTステートメントを一つのINSERTステートメント内の複数のvalues値の形式でまとめることで、バッチINSERTのパフォーマンスを向上させます。
各INSERTをprepareするには、prepareStatement方式を使用して準備し、その後にaddBatchする必要があります。そうでない場合、結合実行はできません。
allowMultiQueries:TRUEに設定することを推奨します。JDBCドライバーは、アプリケーションコードが複数のSQLをセミコロン(;)で結合し、一つのSQLとしてサーバー側に送信することを許可します。
useLocalSessionState:TRUEに設定することを推奨します。これにより、トランザクションが頻繁にOBデータベースにsession変数のクエリSQLを送信するのを避けることができます。session変数は主に以下のものです:autocommit、read_only、transaction isolation。
socketTimeout:SQL実行時に、socketがSQLの返却を待機する時間です。connectTimeout:接続確立時に、接続を待機する時間です。useCursorFetch:TRUEに設定することを推奨します。データ量の多いクエリステートメントについて、データベースサーバーはCursorを確立し、FetchSizeのサイズに応じてClientにデータを配信します。このプロパティを
TRUEに設定すると、useServerPrepStmts=TRUEも自動的に設定されます。useServerPrepStmts:SQLをデータベースサーバーに送信する際にPSプロトコルを使用するかどうかを制御します。TRUEに設定すると、SQLはデータベース内で2段階に分けて実行されます:?を含むSQLテキストをデータベースサーバーに送信してPrepareを行います(SQL_audit: request_type=5)。実際のValueを使用して、データベース内でExecuteを行います(
SQL_audit: request_type=6)。
cachePrepStmts:JDBC driverがPS cacheを有効にしてPreparedStatmentをキャッシュし、prepareの繰り返し実行(client側とserver側)を回避するかどうかを制御します。cachePrepStmts=TRUEは、useServerPrepStmts=TRUEを使用し、同一SQLに対してバッチ実行を繰り返すシナリオに役立ちます。毎回のバッチ実行にはprepareとexecutecachePrepStmts=TRUEにより、繰り返しのprepare操作を回避できます。prepStmtCacheSQLLimit:PS cacheに格納できるSQLの長さの上限です。これを超える長さのSQLはキャッシュに入れることができません。prepStmtCacheSize:PS cacheが保存できるSQLの数です。maxBatchTotalParamsNum:バッチ操作において、一つのSQLがサポートできる最大パラメータ数(つまり、バッチ内の?の数)です。パラメータ数がこの制限を超えると、バッチSQLは分割されます。