竹形誠司 ブログ
ご質問    »トピック一覧
掲示板へのスパムが多いため、「ご質問」のコーナーはユーザー登録制とさせていただきました。お手数ですが、上の「新規ユーザーの登録」メニューより登録をお願いします。
帳票Web
アプリケーション

受注開発始めました
詳しくは こちら
竹形 誠司 著/ラトルズ刊
JSP帳票アプリケーション実践開発入門
JSP帳票アプリケーション
実践開発入門

JSP業務アプリケーション短期開発入門
JSP業務アプリケーション
短期開発入門

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門
Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

Java+MySQL+Tomcatで作る掲示板とブログ
Java+MySQL+Tomcatで作る
掲示板とブログ
MySQLの接続リードタイムとDBCPのパフォーマンスについて
by blushmaple[blushmaple]
MySQLに限っていうとコネクションが非常に高速に確立するので、
DBCPを使わないほうがよいという記事を読んだことがありました。
(メジャーなサイトだったと思いますが、忘れました)
実際のところはどうなのでしょうか。
パフォーマンス比較などの情報があれば教えていただけると幸いです。

投稿:blushmaple[blushmaple]/2008年 04月 23日 06時 50分 /更新:2008年 04月 23日 06時 50分
RE:MySQLの接続リードタイムとDBCPのパフォーマンスについて
by 竹形 誠司[takegata]
竹形です。こんにちは。

>MySQLに限っていうとコネクションが非常に高速に確立するので、
>DBCPを使わないほうがよいという記事を読んだことがありました。

そうですね、以前は私もそう思っていたことがあるのですが、自分でコードを書いてテストしてみた結果、高い負荷がかかった時はDBCPの方が効率が良いような感じでした。

テスト方法は、MySQLの最大同時接続数を少なくして、ループの中で接続と切断を繰り返すようなコードを実行するというものです。ループの回数を増やしつつ、DBCPを使う方法と使わない方法を比較したところ、DBCPを使わないコードで先にエラーが発生しました。

だいぶ昔のことなので、具体的なコードやデータは残っていませんし、いろいろな条件によって結果も変わってくると思います。機会があれば、このあたりのこともちょっと整理してみたいです。
投稿:竹形 誠司[takegata]/2008年 04月 23日 12時 55分 /更新:2008年 04月 23日 12時 57分
RE:MySQLの接続リードタイムとDBCPのパフォーマンスについて
by 竹形 誠司[takegata]
↑の話はかなり曖昧だったので、次のようなコードを新たに書いてテストしてみました。
dbtest1.jsp (DBCPなし)
<%@ page contentType="text/html; charset=utf-8"%>
<%@ page import="java.sql.*"%>
no DBCP<BR>
<%
int n = Integer.parseInt(request.getParameter("n"));
Class.forName("com.mysql.jdbc.Driver");
String strConn = "jdbc:mysql://localhost/test?user=Mulder&password=TrustNo1"
        +"&useUnicode=true&characterEncoding=utf8";
String strSql = "SELECT 1";
long lngStart = System.currentTimeMillis();
for(int i=0;i<n;i++){
        Connection conn= DriverManager.getConnection(strConn);
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(strSql);
        stmt.close();
        rs.close();
        conn.close();
}
long lngStop = System.currentTimeMillis();
%>
repeat <%=n%> times<BR>
time <%=lngStop-lngStart%> ms<BR>
dbtest2.jsp (DBCPあり)
<%@ page contentType="text/html; charset=utf-8"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
DBCP<BR>
<%
int n = Integer.parseInt(request.getParameter("n"));
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/test");
String strSql = "SELECT 1";
long lngStart = System.currentTimeMillis();
for(int i=0;i<n;i++){
        Connection conn= ds.getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(strSql);
        stmt.close();
        rs.close();
        conn.close();
}
long lngStop = System.currentTimeMillis();
%>
repeat <%=n%> times<BR>
time <%=lngStop-lngStart%> ms<BR>
ループを100回にして、交互に10回ずつ計測しました。
DBCPなしDBCPあり
578 ms11 ms
690 ms10 ms
582 ms13 ms
701 ms10 ms
585 ms11 ms
795 ms10 ms
543 ms11 ms
701 ms13 ms
547 ms11 ms
700 ms12 ms


ループを200回にすると、こんな感じです。
DBCPなしDBCPあり
1251 ms20 ms
1285 ms22 ms
1253 ms23 ms
1336 ms21 ms
1245 ms23 ms
1288 ms22 ms
1265 ms20 ms
1247 ms22 ms
1244 ms19 ms
1253 ms21 ms


DBCPありの方がだいぶ速いみたいですね。システムモニタでCPU使用率を見ながらテストしたのですが、DBCPを使った方が明らかに軽い感じです。

環境はOpenSolarisのコンテナ、Tomcatのバージョンは6.0.16、Javaのバージョンは 1.6.0_04、MySQLは5.0.45、JDBCドライバはmysql-connector-java-5.1.5-bin.jarです。
投稿:竹形 誠司[takegata]/2008年 04月 24日 03時 17分 /更新:2008年 04月 24日 19時 58分
RE:MySQLの接続リードタイムとDBCPのパフォーマンスについて
by blushmaple[blushmaple]
情報ありがとうございます。
あいまいな質問にも関わらず、すぐに詳細な調査までしていただいて恐縮です。

スケーリングを考えると、いずれにしてもプーリングは必要だろうな、
と思っていたのですが、耐久面・性能面からも肯定的な結果ということで、
とてもすっきりしました。

※removeAbandoned等は外した性能ですよね。

以上、ありがとうございました。
投稿:blushmaple[blushmaple]/2008年 04月 24日 08時 29分 /更新:2008年 04月 24日 08時 29分
RE:MySQLの接続リードタイムとDBCPのパフォーマンスについて
by 竹形 誠司[takegata]
私も気になっていたいたので、ちょうどよい機会でした。
removeAbandoned は trueにしていました。Tomcatのコンテキストはこんな感じです。
<?xml version='1.0' encoding='utf-8'?>
<Context docBase="/export/home/takegata/tomcat/test/jsp" path="/test">
        <Resource name="jdbc/test"
                removeAbandoned="true"
                removeAbandonedTimeout="60"
                logAbandoned="true"
                auth="Container"
                type="javax.sql.DataSource"
                maxActive="10"
                maxIdle="30"
                maxWait="1000"
                username="Mulder"
                password="TrustNo1"
                driverClassName="com.mysql.jdbc.Driver"
                url="jdbc:mysql://localhost/test?autoReconnect=true&amp;useUnicode=true&am
p;characterEncoding=utf8"
        />
</Context>
DBCPを使う場合は、removeAbandonedに頼るとコネクションのクローズを忘れがちになってしまうのですが、普段は大丈夫でもアクセスが多いときにエラーが出ますから、その辺りは注意が必要ですね。
投稿:竹形 誠司[takegata]/2008年 04月 24日 19時 41分 /更新:2008年 04月 24日 19時 49分