データベース接続プールの設定は、システムとデータベースとの効率的かつ安定した接続を確保するための重要なステップです。適切な接続プールの設定により、データベース接続数を効果的に管理し、高並行性による接続枯渇問題を回避できるだけでなく、適切なタイムアウト設定により無効な接続をタイムリーにクリーンアップし、システム性能を確保することができます。
本記事では、接続プールの基本概念、さまざまな接続プールの比較、選択ガイド、接続プールパラメータの推奨設定、およびJDBC設定における重要なパラメータについて説明します。これにより、開発者がデータベースアクセスを最適化するのに役立ちます。
接続プールの基本概念
データベース接続プールは、データベース接続を管理するための技術です。アプリケーションとデータベースの間に接続プールを構築し、事前に一定数のデータベース接続を作成してメモリ内に保持します。アプリケーションがデータベースにアクセスする必要がある場合、接続プールから直接接続を取得し、使用後は接続プールに返却します。これにより、毎回新しい接続を作成する必要がなくなります。
接続プールの主な利点は以下の通りです:
- パフォーマンスの向上:接続の頻繁な作成と破棄に伴うオーバーヘッドを回避します。
- リソース管理:データベース接続の数を制御し、接続枯渇を防ぎます。
- 接続の再利用:接続の利用率を高め、リソースの無駄遣いを減らします。
- 接続監視:接続状態の監視と統計情報を提供します。
接続プールパラメータ
接続プール設定の推奨事項
マネージメントコンソールの日常的な最小接続数は2つを維持するのが適切です。具体的な数値は、業務の同時実行数やトランザクションの処理時間に応じて調整してください。
接続のアイドルタイムアウト時間を設定します。30分を推奨します。
MySQLのデフォルトでは、接続は8時間後に自動的に切断されますが、クライアント側からはこのプロセスが検知できないため、ダーティコネクションが発生する可能性があります。接続プールは、ハートビートやtestOnBorrowなどのメカニズムを用いて接続の生存状態を確認し、この時間内に接続が使用されない場合は直接切断します。
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をprepareStatement方式でprepareし、その後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が含まれるため、cachePrepStmts=TRUEは繰り返しのprepare操作を回避することができます。prepStmtCacheSQLLimit:PS cacheに格納できるSQLの長さの上限です。長すぎるSQLはキャッシュに入れることができません。prepStmtCacheSize:PS cacheが保存できるSQLの数です。maxBatchTotalParamsNum:バッチ操作において、一つのSQLがサポートできる最大パラメータ数(バッチ内の?の数)です。パラメータ数がこの制限を超えると、バッチSQLは分割されます。