Archive for 12月, 2009

12月 1st, 2009

Commons DBCPパラメータの動作

Posted in Oracle, Tomcat by admin

 Tomcatぜ RAC構成ぜ Oracleぜ JDBC接続のコネクションプーリングを実装している環? の話です。メンテなどぜ RACの片停 DBインスタンスを再起動したい、あるいぜ DB障害ぜ RACの片側インスタンスが落ちてしまった場合、落ちてしまったDBに接続していたコネクションプーリングをアプリケーションが利用するとどうなるか?何も対? を実施していない環? では、接続しているDBサーバとのコネクション圏 得失敗を示すSQLExceptionをアプリケーションが返すはずです。

SQLException:No more data to read from socket
SQLException:OALL8 is in an inconsistent state
SQLException:Io exception: Broken pipe SQLException:Already closed

ただし、DBCPパラメータでコネクションプーリング設定を行っていけば、回避出来るケースもあります。

§ DBCPパラメー゜ url
 urlパラメータぜ JDBCの接続URLを定義するパラメータです。記述フォーマットぜ tnsnames.oraファイルと同じで、RAC構成の場合は? 数ぜ HOSTぜ PORTに対し、LOAD_BALANCEぜ FAILOVER機能を調整して接続設? を調整していぜ ことになると思います。今回の話題で特に重要になるのぜ LOAD_BALANCEです。LOAD_BALANCEをONにした場合、コネクションプーリングのセッションぜ ADDRESS_LISTに登録されているリスナーポートにバランシングされて接続されます。initialSizeが10本ぜ 2DBインスタンスにバランシングする場合、通常ぜ (無風状態ぜ )5本ずつのコネクションがはられます。
 RACの片停 DBインスタンスが停止した場合、停止したDBインスタンス側に接続していたコネクションをアプリケーションが利用すると先に示したSQLExceptionを返すのですが、停止していないDBインスタンス側に接続していたコネクションは通常通り利用可能です。停止したDBインスタンス側に接続していたコネクションも何度かアクセスしてコネクションをリフレッシュさせることによって、停止していないDBインスタンス側に接続するように切り替゜ ります。この時、すべてのコネクションが片停 DBインスタンスに? ることぜ Oracleぜ processes制限を超えないようにセッション数を調整しておぜ ことも重要です。

§ DBCPパラメー゜ validationQuery
 SQLExceptionを発生させないというような可用性を意識するならば、validationQueryパラメータで確認を行います。validationQueryパラメータで接続が有効であることを確? するためぜ SQL文を定義すれば、自動的ぜ testOnBorrowパラメータも有効になり、コネクションの有効性を確? するようになります。validationQueryパラメータで指定したSQL文は別途啜 い合゜ せが実行されることになりますので、少なからずDBサーバに? 荷がかかる事になります。当然ながらなるべく負荷のかからないSQL文を採用します。Tomcatには、OracleAS, Weblogic, Websphereにあるような昜 示的なコネクションリフレッシュ動作をさせる機能はありませんが、この? 能を使用すれば似たような動作が保障されることになります。

§ DBCPパラメー゜ testWhileIdle
 validationQueryと合゜ せぜ testWhileIdleパラメータを有効にすれば、timeBetweenEvictionRunsMillisで指定した時間間隔でアイドル接続の有効性を確? するようになります。(1回でチェックする接続数はデフォルトぜ 3、numTestsPerEvictionRunで指定可能? また、同時ぜ minIdleで最少アイドル接続数を指定することで、常にプール内に? 定数以上の接続が確? しておぜ ことも可能です。
(手元の? 証環? で確認したところ、このパラメータを有効にした時に片側ぜ DBインスタンスが停止した場合、直? に? DBインスタンスのセッションを2セッション? 加させていることを確? しました。DBインスタンス停止直? にも判断できるようになっているのでしょうか・・・? )

上記のようぜ Commons DBCPパラメータをいぜ つか挙げましたが、やはり各環? で? 件に合゜ せてパラメータを? 入・? 証してみるのが一番だと思゜ れます。要件の面ではパフォーマンスを優先させるか可用性を高く保つかで別れてぜ ると思います。下記に極端なパラメータの? を朏 示してみました。高負荷試験を実施した場合や本番環? で稼働させた場合、どの? 度のパフォーマンス差が出てぜ るのかいつか試してみたいところです。

パフォーマンス優先
とにかぜ パフォーマンスのボトルネックとなる無霧 なオプション動作をさせない。validationQueryやremoveAbandoned機能も実施せず、maxActive, initialSize, maxIdleを同数にしてセッションの? 減調整動作もさせない。urlパラメータぜ LOAD_BALANCEぜ OFFにして常に片側ぜ DBインスタンスへ啜 い合゜ せに? かせることで? 分散はアプリケーションパーティショニングで? 施? 、RAC間のキャッシュフュージョンを発生させない。その? 、Prepared Statement関連は全く試したことがないので? 回は? 述していません。

<Resource name="jdbc/DBTEST_PERF"
	auth="Container"
	type="javax.sql.DataSource"
	driverClassName="oracle.jdbc.OracleDriver"
	url="jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)
		(ADDRESS_LIST=
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.1)(PORT=1522))
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.5)(PORT=1522))
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.1)(PORT=1523))
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.5)(PORT=1523))
		(LOAD_BALANCE=OFF)(FAILOVER=ON))
		(CONNECT_DATA=(SERVICE_NAME=DBINST)(SERVER=DEDICATED)))"
	username="SCHEMA"
	password="PASSWORD"
	maxActive="10"
	maxIdle="10"
	initialSize="10"
	maxWait="5000"
/>

障害対応 可用性優先
validationQueryやremoveAbandoned、testWhileIdle機能をすべて有効にしておぜ 。urlパラメータぜ LOAD_BALANCEぜ ONにして? 荷分散朧 成とする。

<Resource name="jdbc/DBTEST_AVAIL"
	auth="Container"
	type="javax.sql.DataSource"
	driverClassName="oracle.jdbc.OracleDriver"
	url="jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)
		(ADDRESS_LIST=
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.1)(PORT=1522))
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.5)(PORT=1522))
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.1)(PORT=1523))
		(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.5)(PORT=1523))
		(LOAD_BALANCE=ON)(FAILOVER=ON))
		(CONNECT_DATA=(SERVICE_NAME=DBINST)(SERVER=DEDICATED)))"
	username="SCHEMA"
	password="PASSWORD"
	maxActive="10"
	maxIdle="10"
	initialSize="10"
	maxWait="5000"
	removeAbandoned="true"
	removeAbandonedTimeout="300"
	logAbandoned="true"
	validationQuery="select 1 from dual"
	testWhileIdle="true"
	timeBetweenEvictionRunsMillis="30000"
	minIdle="10"
	numTestsPerEvictionRun="10"
/>