データベース接続プールの設定は、システムとデータベースとの効率的で安定した接続を確保するための重要なステップです。適切な接続プールの設定は、データベース接続数を効果的に管理し、高並行性による接続枯渇問題を回避するだけでなく、適切なタイムアウト設定により無効な接続をタイムリーにクリーンアップし、システム性能を確保することができます。
本記事では、接続プールの基本概念、さまざまな接続プールの比較、選択ガイド、接続プールパラメータの推奨設定、およびJDBC設定における重要なパラメータについて紹介し、開発者がデータベースアクセスを最適化するのに役立てていただきます。
接続プールの基本概念
データベース接続プールは、データベース接続を管理する技術です。アプリケーションとデータベースの間に接続プールを構築し、あらかじめ一定数のデータベース接続を作成してメモリ内に保持します。アプリケーションがデータベースにアクセスする必要がある場合、接続プールから直接接続を取得し、使用後は接続プールに返却します。これにより、毎回新しい接続を作成する必要がありません。
接続プールの主な利点は以下のとおりです:
- パフォーマンスの向上:接続の頻繁な作成と破棄に伴うオーバーヘッドを回避します。
- リソース管理:データベース接続数を制御し、接続枯渇を防ぎます。
- 接続の再利用:接続の利用率を向上させ、リソースの無駄遣いを減らします。
- 接続監視:接続状態の監視と統計情報を提供します。
接続プールパラメータ
接続プールには通常、以下のコアパラメータが含まれます:
- 初期接続数:接続プールの初期化時に作成される接続数。
- 最小接続数:接続プール内で維持される最小接続数。
- 最大接続数:接続プール内で許可される最大接続数。
- 接続タイムアウト時間:接続を取得するための最大待機時間。
- アイドルタイムアウト時間:プール内でアイドル状態の接続が保持できる最大時間。この時間を超えると接続は回収されます。
- 検出間隔:アイドル接続をチェックする間隔時間。
- 検出クエリ:接続が有効かどうかを検出するために使用されるSQLクエリ。
接続プール設定の推奨事項
管理コンソールの日常的なminは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を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:PSプロトコルを使用してSQLをデータベースサーバーに送信するかどうかを制御します。TRUEに設定すると、SQLはデータベース内で2段階に分けて実行されます:?を含むSQLテキストをデータベースサーバーに送信してPrepareを行います(SQL_audit: request_type=5)。実際のValueを使用して、データベース内でExecuteを行います(
SQL_audit: request_type=6)。
cachePrepStmts:JDBCドライバーがPS cacheを有効にしてPreparedStatmentをキャッシュし、prepareの繰り返し実行(client側およびserver側)を回避するかどうかを制御します。cachePrepStmts=TRUEは、useServerPrepStmts=TRUEを使用し、同一SQLに対してバッチ実行を繰り返すシナリオで役立ちます。毎回のバッチ実行にはprepareとexecutecachePrepStmts=TRUEにより、繰り返しのprepare操作を回避できます。prepStmtCacheSQLLimit:PSキャッシュに格納できるSQLの最大長制限です。この長さを超えるSQLはキャッシュに入りません。prepStmtCacheSize:PSキャッシュが保存できるSQLの数です。maxBatchTotalParamsNum:バッチ操作において、1つのSQLがサポートできるパラメータの最大数(バッチ内の?の数)です。パラメータ数がこの制限を超えると、バッチSQLは分割されます。