MySQLに限っていうとコネクションが非常に高速に確立するので、
DBCPを使わないほうがよいという記事を読んだことがありました。
(メジャーなサイトだったと思いますが、忘れました)
実際のところはどうなのでしょうか。
パフォーマンス比較などの情報があれば教えていただけると幸いです。
DBCPを使わないほうがよいという記事を読んだことがありました。
(メジャーなサイトだったと思いますが、忘れました)
実際のところはどうなのでしょうか。
パフォーマンス比較などの情報があれば教えていただけると幸いです。
投稿:blushmaple[blushmaple]/2008年 04月 23日 06時 50分
/更新:2008年 04月 23日 06時 50分
RE:MySQLの接続リードタイムとDBCPのパフォーマンスについて
by 竹形 誠司[takegata]
竹形です。こんにちは。
>MySQLに限っていうとコネクションが非常に高速に確立するので、
>DBCPを使わないほうがよいという記事を読んだことがありました。
そうですね、以前は私もそう思っていたことがあるのですが、自分でコードを書いてテストしてみた結果、高い負荷がかかった時はDBCPの方が効率が良いような感じでした。
テスト方法は、MySQLの最大同時接続数を少なくして、ループの中で接続と切断を繰り返すようなコードを実行するというものです。ループの回数を増やしつつ、DBCPを使う方法と使わない方法を比較したところ、DBCPを使わないコードで先にエラーが発生しました。
だいぶ昔のことなので、具体的なコードやデータは残っていませんし、いろいろな条件によって結果も変わってくると思います。機会があれば、このあたりのこともちょっと整理してみたいです。
>MySQLに限っていうとコネクションが非常に高速に確立するので、
>DBCPを使わないほうがよいという記事を読んだことがありました。
そうですね、以前は私もそう思っていたことがあるのですが、自分でコードを書いてテストしてみた結果、高い負荷がかかった時はDBCPの方が効率が良いような感じでした。
テスト方法は、MySQLの最大同時接続数を少なくして、ループの中で接続と切断を繰り返すようなコードを実行するというものです。ループの回数を増やしつつ、DBCPを使う方法と使わない方法を比較したところ、DBCPを使わないコードで先にエラーが発生しました。
だいぶ昔のことなので、具体的なコードやデータは残っていませんし、いろいろな条件によって結果も変わってくると思います。機会があれば、このあたりのこともちょっと整理してみたいです。
投稿:竹形 誠司[takegata]/2008年 04月 23日 12時 55分
/更新:2008年 04月 23日 12時 57分
↑の話はかなり曖昧だったので、次のようなコードを新たに書いてテストしてみました。
dbtest1.jsp (DBCPなし)
ループを200回にすると、こんな感じです。
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です。
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 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>
<%@ 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回ずつ計測しました。<%@ 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>
DBCPなし | DBCPあり |
578 ms | 11 ms |
690 ms | 10 ms |
582 ms | 13 ms |
701 ms | 10 ms |
585 ms | 11 ms |
795 ms | 10 ms |
543 ms | 11 ms |
701 ms | 13 ms |
547 ms | 11 ms |
700 ms | 12 ms |
ループを200回にすると、こんな感じです。
DBCPなし | DBCPあり |
1251 ms | 20 ms |
1285 ms | 22 ms |
1253 ms | 23 ms |
1336 ms | 21 ms |
1245 ms | 23 ms |
1288 ms | 22 ms |
1265 ms | 20 ms |
1247 ms | 22 ms |
1244 ms | 19 ms |
1253 ms | 21 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分
情報ありがとうございます。
あいまいな質問にも関わらず、すぐに詳細な調査までしていただいて恐縮です。
スケーリングを考えると、いずれにしてもプーリングは必要だろうな、
と思っていたのですが、耐久面・性能面からも肯定的な結果ということで、
とてもすっきりしました。
※removeAbandoned等は外した性能ですよね。
以上、ありがとうございました。
あいまいな質問にも関わらず、すぐに詳細な調査までしていただいて恐縮です。
スケーリングを考えると、いずれにしてもプーリングは必要だろうな、
と思っていたのですが、耐久面・性能面からも肯定的な結果ということで、
とてもすっきりしました。
※removeAbandoned等は外した性能ですよね。
以上、ありがとうございました。
投稿:blushmaple[blushmaple]/2008年 04月 24日 08時 29分
/更新:2008年 04月 24日 08時 29分
私も気になっていたいたので、ちょうどよい機会でした。
removeAbandoned は trueにしていました。Tomcatのコンテキストはこんな感じです。
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&useUnicode=true&am
p;characterEncoding=utf8"
/>
</Context>
DBCPを使う場合は、removeAbandonedに頼るとコネクションのクローズを忘れがちになってしまうのですが、普段は大丈夫でもアクセスが多いときにエラーが出ますから、その辺りは注意が必要ですね。<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&useUnicode=true&am
p;characterEncoding=utf8"
/>
</Context>
投稿:竹形 誠司[takegata]/2008年 04月 24日 19時 41分
/更新:2008年 04月 24日 19時 49分