社内で「コネクションプールって何ですか?なぜ要るんですか?」という素朴な疑問が発生したので、Oracle Database をモデルにして簡単に説明してみますやで。
彡(゚)(゚)
1. 前提知識1:Oracle Database のプロセス・アーキテクチャ
Oracle Database は UNIX/Linuxプラットフォーム の場合はマルチプロセスのアーキテクチャが採用されています。
Oracle Databaseデータベース概要 19c
15 プロセス・アーキテクチャ
https://docs.oracle.com/cd/F19136_01/cncpt/process-architecture.html#GUID-85D9852E-5BF1-4AC0-9E5A-49F0570DBD7A
プロセス実行のアーキテクチャは、オペレーティング・システムによって決まります。
たとえば、Windowsでは、Oracleバックグラウンド・プロセスはプロセス内の実行スレッドです。
LinuxおよびUNIXにおけるOracleプロセスは、オペレーティング・システム・プロセスか、またはオペレーティング・システム・プロセス内部のスレッドです。
Oracle Database では DB接続時 にサーバープロセスが生成されます。そのサーバープロセスとクライアント(SQLを発行するアプリケーション)が SQL をやり取りをすることで、様々な処理が行われます。マルチプロセスのアーキテクチャは下記マニュアルの図が全体感を掴むのに良いです。
Oracle Database データベース概要 19c - Oracle Databaseアーキテクチャ
https://docs.oracle.com/cd/F19136_01/cncpt/introduction-to-oracle-database.html#GUID-CF765A7D-9429-4901-BF33-36E0B0220293
2. 前提知識2: Oracle Database のリスナー経由での接続処理とその問題
Oracle Database では大半のケースでリスナーに接続要求をしてサーバープロセスを生成します。
Oracle Databaseによるサーバー・プロセスの作成方法
https://docs.oracle.com/cd/F19136_01/cncpt/process-architecture.html#GUID-13FE4098-61DF-4D76-882D-551A88E0EBB8
接続にBequeathが使用されないときは、データベースによって次のようにサーバー・プロセスが作成されます。
- クライアント・アプリケーションがリスナーまたはブローカから新規の接続をリクエストします。
- リスナーまたはブローカが新規のプロセスまたはスレッドの作成を開始します。
- オペレーティング・システムが新規のプロセスまたはスレッドを作成します。
- Oracle Databaseが各種のコンポーネントおよび通知を初期化します。
- データベースが接続および接続固有コードを引き渡します。
この接続時の処理はとても負荷が高い処理 かつ リスナーでシリアライズ(順番待ち)されるため、秒間何千何万ものSQLを処理しようとするとこの接続時の処理がボトルネックになって性能(スループット/レスポンス)がスケールしにくくなります。これが直後のコネクションプールが必要とされる理由となります。
3. コネクションプールとは?
コネクションプールはアプリケーション側(クライアント側)で予め一定数のDB接続を確保しておいて、それをアプリケーションで使い廻す仕組みです。DB接続を予め実行して貯めて(プールして)おき、その接続をアプリケーションで共有して接続時の高負荷を回避します。下記リンクが解り易いでしょうか。
コネクションプーリング
https://e-words.jp/w/%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0.html
外部のプログラムがデータベースの内容を読み書きする場合、DBMSへ処理を依頼するが、そのためにはデータを送受信するコネクション(connection)の確立を行う必要がある。接続や切断の処理を行うたびに一定の負荷が生じるため、頻繁にアクセスが行われるシステムではこのオーバーヘッドのために性能が劣化する場合がある。
コネクションプーリングの仕組みを自分で実装する事も可能ですが、例えば Java でアプリケーションサーバー(Oracle WebLogic Server や Tomcat, IBM WebSphereなど)を採用する場合は、アプリケーションサーバー側でコネクションプールの仕組みが実装されているため、その仕組みを利用する事が多いはずです。
下記は WebLogic のコネクションプーリングの仕組みである、JDBCデータ・ソースのマニュアルです。
WebLogic Server JDBCデータ・ソースのタイプ
https://docs.oracle.com/cd/F32751_01/weblogic-server/14.1.1.0/jdbca/jdbc_datasources.html#GUID-D030B12E-DE55-46DA-90B5-E17CB54F9A71
近年はコンテナ技術の台頭でアプリケーション側でコネクションを保持しておく事が難しいケースもあります。コンテナはコンテナ自身の生成や破棄を繰り返すのが前提になり、コンテナ破棄のタイミングでDB接続も失われるからです。OCI FunctionsやAWS Lambdaの様なサーバーレス処理でも同様の問題が発生し得ます。また採用する言語やフレームワークによってはコネクションプーリングの仕組みが無い場合もあります。
そのようなケースではデータストア側でコネクションプールと同等の仕組みが提供される場合もあります。Oracle Database の場合は データベース常駐接続プーリング(DRCP)、クラウドだと AWS の RDS Proxy がデータストア側のコネクションプーリングに相当します。
データベース常駐接続プーリング(DRCP)
https://docs.oracle.com/cd/F19136_01/cncpt/application-and-networking-architecture.html#GUID-531EEE8A-B00A-4C03-A2ED-D45D92B3F797Autonomous Databaseでのデータベース常駐接続プーリング(DRCP)の使用
https://docs.oracle.com/cd//E83857_01/paas/autonomous-database/adbsa/connect-drcp.htmlAmazon RDS Proxy
https://aws.amazon.com/jp/rds/proxy/
4. コネクションプールによって発生する問題と回避策
コネクションプールによって発生する問題として無効接続が挙げられます。サーバープロセス側で問題が発生(プロセスのクラッシュやインスタンスダウン等)すると、そのサーバープロセスにクライアント側から SQL を実行するとハングしてしまいます(無効接続)。
無効接続問題を回避するため、多くのアプリケーションサーバー(WebLogicなど)ではコネクションプールの健全性をチェックする仕組みを備えています。下記は WebLogic の該当機能のマニュアルとなります。
WebLogic: 定期的な接続テスト
https://docs.oracle.com/cd/F32751_01/weblogic-server/14.1.1.0/jdbca/ds_tuning.html#GUID-E379C967-EFEC-444A-9F4F-C822E933A33F
Oracle Database の場合は FAN/FCF という仕組みを備えています。アプリケーションサーバー側(WebLogic等)にインスタンスダウン等のイベントを通知(FAN)して、アプリケーションサーバー側で無効になった接続を破棄して再接続(FCF)します。データストア側からのイベント通知で動作するため、ポーリング型のSQL定期実行よりも問題を回避し易くなり可用性が向上します。
Oracle Database 機能概要(P.199, 高速アプリケーション通知, Fast Application Notification: FAN)
https://speakerdeck.com/oracle4engineer/oracle-database-ji-neng-gai-yao?slide=199
5. まとめ
コネクションプールを使用するとDB/データストア接続時の高負荷を回避できます。
皆さん上手くコネクションプールを活用しましょうね。
彡(^)(^)
Appendix1. Oracle WebLogic Server のコネクションプール(JDBCデータソース)について
Oracle社製の Javaアプリケーションサーバーである WebLogic では様々な種類のコネクションプール(JDBCデータソース)が有ります。
それらのデータソースについてざっくりと解説彡(゚)(゚)
4 デフォルト・データ・ソース(汎用データソース)の使用
https://docs.oracle.com/cd/F32751_01/weblogic-server/14.1.1.0/jdbca/default_datasource.html#GUID-EE3DAF88-3D79-4271-803E-A288ECEE211D
デフォルト・データソース(汎用データソース)は Java EE 7ランタイム に準拠した JDBC のコネクションプールとなります。JDBCコネクションプールの標準的な機能を提供します。
5 JDBCマルチ・データ・ソースの構成
https://docs.oracle.com/cd/F32751_01/weblogic-server/14.1.1.0/jdbca/jdbc_multidatasources.html#GUID-CF34E3FE-C329-4006-9506-34544B8447CD
JDBCマルチ・データソースは複数の汎用データソースをグループ化/抽象化したものとなります。その特性から事実上Oracle RAC専用?ということになるでしょうか。
Oracle RAC の DBノード(インスタンス) と 1vs1 で対応する汎用データソースをDBノード数分作成しておいて、マルチデータソースでそれらの汎用データソースをグループ化します。Oracle RAC のDBノードやインスタンスで障害が発生するとそのDBノード(インスタンス)に対応する汎用データソースは無効化されて、SQL実行は他の汎用データソース(DBノード)にバランシングされます。
マルチデータソースを利用するアプリケーション側からはDB障害は隠蔽されて、結果として可用性が向上します。
6 Active GridLinkデータ・ソースの使用方法
https://docs.oracle.com/cd/F32751_01/weblogic-server/14.1.1.0/jdbca/gridlink_datasources.html#GUID-82D615E4-857E-4DC1-89D2-34270809690A
Active GridLink は前述の FAN(高速アプリケーション通知)/FCF(Fast Connection Failover) や RCLB(ランタイム接続ロード・バランス)、後述の Application Continuity(アプリケーション・コンティニュイティ)など Oracle RAC や Active Data Guard と高度に連携する機能を備えた JDBCデータソースとなり、主に高可用性にメリットが有ります。利用には WebLogic Suite のライセンスが必要です。
7 ユニバーサル接続プール(UCP)・データ・ソースの使用
https://docs.oracle.com/cd/F32751_01/weblogic-server/14.1.1.0/jdbca/ucp_datasources.html#GUID-91994E4A-5B7B-42A1-9584-9E1AB579FD40Universal Connection Pool開発者ガイド
https://docs.oracle.com/cd/F19136_01/jjucp/index.html
UCPデータソースは Oracle が (WebLogicとは独立して)提供する UCP(Universal Connection Pool) の機能を利用可能なデータソースとなります。前述の Active GridLinkよりも制限は多いですが FAN/FCF や下記の Application Continuity を使用でき、可用性が向上します。
アプリケーション・コンティニュイティ対応クライアント
https://speakerdeck.com/oracle4engineer/apurikesiyonkonteiniyuitei?slide=33
Appendix2. アプリケーション・コンティニュイティ(Application Continuity)について
アプリケーション・コンティニュイティ(Application Continuity) は Oracle Database のエラー発生時に実行中のトランザクションをエラー時点から再実行する機能となります。トランザクションの再実行でエラーがクライアント側から隠蔽され、結果として可用性が向上します。
アプリケーション・コンティニュイティ
https://speakerdeck.com/oracle4engineer/apurikesiyonkonteiniyuiteiアプリケーション・コンティニュイティについて
https://docs.oracle.com/cd/F19136_01/racad/ensuring-application-continuity.html#GUID-BD699AEB-9F85-42A8-8687-5A979918938DApplication Continuity を Java の UCP(ucp.jar) と Autonomous Database の ATP で試してみる。(Oracle Cloud Infrastructure)
https://qiita.com/ora_gonsuke777/items/5e348a4f444b2d3643d0
コネクションプーリングとは独立した機能なので Appendix としていますが、FAN/FCF等と併用することで可用性向上が可能です。