MongoDB,CouchDB,MySQL,memcacheデータをPHPから読み込み&書き込み速度を検証してみました!
前回、前前回とMongoDB,CouchDBのインストール方法やphpからの使用方法を記事にしました。
CentOS5.4にCouchDBをインストールする方法! - @camelmasaの開発日記
CouchDBをphpから操作する方法。 - @camelmasaの開発日記
CentOS5.4にMongoDBをインストールする方法! - @camelmasaの開発日記
MongoDBをphpから操作する方法。 - @camelmasaの開発日記
MongoDBとCouchDBにMySQL(MyISAM)とmemcacheを加えて読み込み(SELECT)と書き込み(INSERT)の速度を検証してみたいと思います。
環境
OS:CentOS5.4
PHP:5.3.1
MongoDB:1.2.2
CouchDB:0.10.1
MySQL:5.1.43
memcache:1.2.8
CPU:AMD(の何か)
メモリ:4GB
(ざっくりと検証です。)
読み取り時のソース
簡単に、"test"データベースの"test"テーブル(コレクション)の"test"データをphpから読み込みするプログラムです。
こんなソースで良いのか。
<?php require_once "HTTP/Request.php"; $http = new HTTP_Request('http://192.168.80.139:5984/test/93e4b62c166489b5ff94600e3003db88'); $response = $http->sendRequest();
mongodb.php
<?php $mongo = new Mongo(); $db = $mongo->selectDB("test"); $col = $db->selectCollection("test"); $cursor = $col->findOne();
<?php $link = mysql_pconnect('localhost', 'user', 'pass'); mysql_select_db('mytest', $link); $result = mysql_query('SELECT `test` FROM `test`;');
memcache.php
<?php $memcache = new Memcache; $memcache->connect('localhost', 11211) or die ("Could not connect"); $memcache->get('test');
読み込み結果
ab -c 100 -n 1000 'http://192.168.0.30/couchdb.php' This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.0.30 (be patient) Server Software: Apache/2.2.3 Server Hostname: 192.168.0.30 Server Port: 80 Document Path: /couchdb.php Document Length: 0 bytes Concurrency Level: 100 Time taken for tests: 9.587989 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 190000 bytes HTML transferred: 0 bytes Requests per second: 104.30 [#/sec] (mean) Time per request: 958.799 [ms] (mean) Time per request: 9.588 [ms] (mean, across all concurrent requests) Transfer rate: 19.29 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.5 0 9 Processing: 22 926 923.1 650 9554 Waiting: 21 860 568.4 650 5877 Total: 22 927 923.5 650 9555 Percentage of the requests served within a certain time (ms) 50% 650 66% 662 75% 783 80% 1099 90% 1565 95% 1735 98% 3220 99% 5656 100% 9555 (longest request)
mongodb.php
ab -c 100 -n 1000 'http://192.168.0.30/mongodb.php' This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.0.30 (be patient) Server Software: Apache/2.2.3 Server Hostname: 192.168.0.30 Server Port: 80 Document Path: /mongodb.php Document Length: 0 bytes Concurrency Level: 100 Time taken for tests: 1.939626 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 190000 bytes HTML transferred: 0 bytes Requests per second: 515.56 [#/sec] (mean) Time per request: 193.963 [ms] (mean) Time per request: 1.940 [ms] (mean, across all concurrent requests) Transfer rate: 95.38 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.5 0 8 Processing: 35 187 35.4 201 236 Waiting: 35 187 35.4 201 235 Total: 35 187 35.2 201 244 Percentage of the requests served within a certain time (ms) 50% 201 66% 202 75% 204 80% 204 90% 207 95% 208 98% 209 99% 226 100% 244 (longest request)
ab -c 100 -n 1000 'http://192.168.0.30/mysql.php' This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.0.30 (be patient) Server Software: Apache/2.2.3 Server Hostname: 192.168.0.30 Server Port: 80 Document Path: /mysql.php Document Length: 0 bytes Concurrency Level: 100 Time taken for tests: 1.421236 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 190000 bytes HTML transferred: 0 bytes Requests per second: 703.61 [#/sec] (mean) Time per request: 142.124 [ms] (mean) Time per request: 1.421 [ms] (mean, across all concurrent requests) Transfer rate: 130.17 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 5.1 0 22 Processing: 7 131 142.4 129 1404 Waiting: 7 131 142.3 129 1403 Total: 19 133 142.6 129 1416 Percentage of the requests served within a certain time (ms) 50% 129 66% 130 75% 136 80% 138 90% 141 95% 144 98% 173 99% 1339 100% 1416 (longest request)
memcache.php
ab -c 100 -n 1000 'http://192.168.0.30/memcache.php'
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.0.30 (be patient)
Server Software: Apache/2.2.3
Server Hostname: 192.168.0.30
Server Port: 80
Document Path: /memcache.php
Document Length: 0 bytes
Concurrency Level: 100
Time taken for tests: 1.453866 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 191900 bytes
HTML transferred: 0 bytes
Requests per second: 687.82 [#/sec] (mean)
Time per request: 145.387 [ms] (mean)
Time per request: 1.454 [ms] (mean, across all concurrent requests)
Transfer rate: 128.62 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 15 10.2 14 45
Processing: 20 124 36.9 138 479
Waiting: 16 109 35.7 119 462
Total: 27 139 41.8 147 496
Percentage of the requests served within a certain time (ms)
50% 147
66% 163
75% 172
80% 176
90% 186
95% 191
98% 198
99% 203
100% 496 (longest request)
読み込み結果検証
Requests per secondの順位下記。
MySQL(MyISAM)>memcache>MongoDB>>>CouchDB
MySQLが一番早い結果になるとは思わなかったです。(なって欲しくなかった)
でもFacebookでのMySQL運用術はKVSの様にシンプルなのかな。
(http://hyuki.com/yukiwiki/wiki.cgi?HowFriendFeedUsesMySqlToStoreSchemaLessData)
CouchDBはRESTでのデータ取得をPEARでやってしまってるので遅いのかな?
毎度毎度その処理部分のPHPをコンパイルする分遅くなっているのでしょう。
MongoDBもmemcache並に早いですね。
MySQLがmemcacheより早いのは意外です。解せぬ〜。
次は書き込み時の速さを見てみます。
書き込み時のソース
couchdbはinsertの方法が調べれず…><
誰か教えて!ヘルプ!
mongodb_write.php
<?php $mongo = new Mongo(); $db = $mongo->selectDB("test"); $col = $db->selectCollection("test"); $col->insert(array("test" => "test"));
<?php $link = mysql_pconnect('localhost', 'root', ''); mysql_select_db('mytest', $link); $result = mysql_query("INSERT INTO `test` VALUES ('test');");
memcache_write.php
<?php $memcache = new Memcache; $memcache->connect('localhost', 11211) or die ("Could not connect"); $memcache->set("test", "test");
書き込み結果
mongodb_write.php
ab -c 100 -n 1000 'http://192.168.0.30/mongodb_write.php' This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.0.30 (be patient) Server Software: Apache/2.2.3 Server Hostname: 192.168.0.30 Server Port: 80 Document Path: /mongodb_write.php Document Length: 0 bytes Concurrency Level: 100 Time taken for tests: 9.325888 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 190190 bytes HTML transferred: 0 bytes Requests per second: 107.23 [#/sec] (mean) Time per request: 932.589 [ms] (mean) Time per request: 9.326 [ms] (mean, across all concurrent requests) Transfer rate: 19.84 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 4 9.7 0 36 Processing: 30 728 1111.7 176 9092 Waiting: 3 725 1112.6 176 9091 Total: 31 732 1111.0 177 9108 Percentage of the requests served within a certain time (ms) 50% 177 66% 910 75% 937 80% 938 90% 1030 95% 3103 98% 3148 99% 4285 100% 9108 (longest request)
ab -c 100 -n 1000 'http://192.168.0.30/mysql_write.php' This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.0.30 (be patient) Server Software: Apache/2.2.3 Server Hostname: 192.168.0.30 Server Port: 80 Document Path: /mysql_write.php Document Length: 0 bytes Concurrency Level: 100 Time taken for tests: 1.484070 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 190000 bytes HTML transferred: 0 bytes Requests per second: 673.82 [#/sec] (mean) Time per request: 148.407 [ms] (mean) Time per request: 1.484 [ms] (mean, across all concurrent requests) Transfer rate: 124.66 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.6 0 8 Processing: 41 142 165.8 129 1478 Waiting: 40 142 165.8 129 1478 Total: 41 143 165.8 129 1479 Percentage of the requests served within a certain time (ms) 50% 129 66% 131 75% 132 80% 133 90% 139 95% 144 98% 161 99% 1476 100% 1479 (longest request)
memcache_write.php
ab -c 100 -n 1000 'http://192.168.0.30/memcache_write.php' This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.0.30 (be patient) Server Software: Apache/2.2.3 Server Hostname: 192.168.0.30 Server Port: 80 Document Path: /memcache_write.php Document Length: 0 bytes Concurrency Level: 100 Time taken for tests: 1.701421 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 190380 bytes HTML transferred: 0 bytes Requests per second: 587.74 [#/sec] (mean) Time per request: 170.142 [ms] (mean) Time per request: 1.701 [ms] (mean, across all concurrent requests) Transfer rate: 108.73 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 17 11.0 18 44 Processing: 34 143 24.8 148 267 Waiting: 3 126 25.6 132 261 Total: 34 160 28.3 163 301 Percentage of the requests served within a certain time (ms) 50% 163 66% 175 75% 181 80% 185 90% 192 95% 195 98% 201 99% 205 100% 301 (longest request)
全体を通したまとめ
大分ざっくりとした検証で納得がいくのかわかりませんが個人的には概ね満足。
インストール〜設定〜動作等で見えた部分は勉強になりました。
検証前は圧倒的にmemcacheが一番早いだろうと思ったのですが、読み書きともMySQLとほぼ同じ位で驚きました。
その後僅差でMongoDB。
CouchDBはhttp通信をphpでしてしまってるので良い結果が得られなかった感じですか。
(couchdb.so作って!)
恐らく皆さんが書いているように、RDBMSも単体では速度的に問題なくて、複雑なSQLを処理しようとするとボトルネックになるのでしょうか。
スケーリングを意識したSQLを書く事で、KVS並に高速化になるのかもしれません。
参考:http://hyuki.com/yukiwiki/wiki.cgi?HowFriendFeedUsesMySqlToStoreSchemaLessData
あとがき
うーん…。
こうしたらMongoDBが早くなるよ!的なアドバイス欲しいな〜。
上記のテストサーバーは家でそのままにしてあるので、こんなテストして!っていう場合コメント下さい。
テストしてブログに書きます。
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
Oracle OpenWorld Tokyo 2009 1日目に参加しました。&アンカンファレンスで講演をしました!
昨日Oracle OpenWorld Tokyo 2009 1日目に参加しました。
そしてアンカンファレンスで講演をしました!
Oracle OpenWorld Tokyo 2009 1日目午前
Oracle OpenWorld Tokyo 2009 1日目午前中は、私のアンカンファレンスでの講演がありましたので、自分の準備で精一杯でした。
※後日slideshareとYouTubeにてプレゼンテーションの様子をアップロードしたいと思います。
福岡さんが私のアンカンファレンスの記事の感想を書いてくれました!
感激!
camelmasaさんのUnconferenceが終了: DFJJ
Oracle OpenWorld Tokyo 2009 1日目午後
午後〜夕方は知人と会ってまして、それからもとくんβさんのアンカンファレンスを聞きました。
もとくんβさんのアンカンファレンスで学んだことは
を学びました。
また、CDでBICSというエクセルのマクロで簡単にマニュアルが作成出来るツールを頂きました。
アンカンファレンス後、挨拶に行ったところ「名刺はフリーエンジニアにとってとても大事なもの」と教えて頂きました。
私は金銭面から手作りで名刺を作成しているのですが、どうしても家のプリンターでは綺麗に印刷できないんですね。
どうにか綺麗に印刷する方法を考えるか、早く名刺をオリジナルで作成できるほどの経済力を身につけるかですかね(笑)
18:30からはMr円で有名な早稲田大学教授榊原さんの「世界同時不況下での経営」という特別講演を聞きました。
榊原英資 - Wikipedia
世界同時不況は構造的な問題なので、まだまだ状況は悪くなる可能性があるそうです。
Oracle OpenWorld Tokyo 2009 1日目を終えて
様々なエンジニアの方とお知り合いになれた事がとても嬉しい一日でした。
一番驚きなのが、私がアンカンファレンスという機会を頂いてエンジニアの皆さんにプレゼンテーションしたことです。
私がエンジニアに向けて技術の話をする事なんて、昨年の私は想像も出来ませんでした。
一皮剥けた感じがします。
この様な機会を与えてくれたオラクル社に感謝したいと思います!
有難うございました!
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
phpを使用してOracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。Oracle Database XE編
MySQLのコネクションプーリングは約2倍の性能結果が出ました。(同時100接続で100万回リクエストのApache Benchを実行した場合)
Oracle Database XEでのコネクションプーリングはどうでしょうか?検証してみたいと思います。
まずはOracle Database XEのコネクションプーリングしない方法で検証です。
コネクションプーリングしないプログラムで100万回リクエストのApache Benchを実行
下記のスクリプトを実行
oracle_connect.php
<?php $link = oci_connect('system', '[パスワード]', 'xe'); $result = oci_parse($link, "SELECT 1;"); oci_close($link); ?>
Apache Benchの実行
ab -n 1000000 -c 100 http://localhost/oracle_connect.php
Apache Benchの実行結果
[root@www html]# ab -n 1000000 -c 100 http://localhost/oracle_connect.php
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests
Server Software: Apache/2.2.3
Server Hostname: localhost
Server Port: 80Document Path: /oracle_connect.php
Document Length: 0 bytesConcurrency Level: 100
Time taken for tests: 1259.278234 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Total transferred: 190000000 bytes
HTML transferred: 0 bytes
Requests per second: 794.11 [#/sec] (mean)
Time per request: 125.928 [ms] (mean)
Time per request: 1.259 [ms] (mean, across all concurrent requests)
Transfer rate: 147.34 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 18.5 0 691
Processing: 0 122 249.2 61 9350
Waiting: 0 115 238.9 61 9349
Total: 0 125 251.4 61 9350Percentage of the requests served within a certain time (ms)
50% 61
66% 63
75% 77
80% 100
90% 208
95% 383
98% 907
99% 1378
100% 9350 (longest request)
Time taken for tests: 1259.278234 secondsなので、約21分かかりました。
かなり遅い結果ですねー…。
逆にコネクションプーリングした際とどれ位差があるのか気になります。
コネクションプーリングの検証をする前に気になった記事がありましたのでこちらも検証しました。
oci_pconnectの第4引数を指定するとパフォーマンス向上 - Do You PHP はてブロ
コネクションプーリングしないプログラムで100万回リクエストのApache Benchを実行(接続時キャラクタセットを指定)
下記のスクリプトを実行
oracle_connect2.php
<?php $link = oci_connect('system', '[パスワード]', 'xe', 'JA16SJIS'); $result = oci_parse($link, "SELECT 1;"); oci_close($link); ?>
Apache Benchの実行
ab -n 1000000 -c 100 http://localhost/oracle_connect2.php
Apache Benchの実行結果
[root@www html]# ab -n 1000000 -c 100 http://localhost/oracle_connect2.php
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests
Server Software: Apache/2.2.3
Server Hostname: localhost
Server Port: 80Document Path: /oracle_connect2.php
Document Length: 0 bytesConcurrency Level: 100
Time taken for tests: 1176.803295 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Total transferred: 190000000 bytes
HTML transferred: 0 bytes
Requests per second: 849.76 [#/sec] (mean)
Time per request: 117.680 [ms] (mean)
Time per request: 1.177 [ms] (mean, across all concurrent requests)
Transfer rate: 157.67 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 21.7 0 609
Processing: 0 113 227.8 54 7051
Waiting: 0 104 213.3 54 7050
Total: 0 117 231.5 54 7051Percentage of the requests served within a certain time (ms)
50% 54
66% 57
75% 75
80% 92
90% 209
95% 376
98% 765
99% 1358
100% 7051 (longest request)
Time taken for tests: 1176.803295 secondsなので、約20分かかりました。
さほど変わらず遅いですが、id:shimookaさんの記事の通り少し早くなりましたね。
次にOracle Database XEのコネクションプーリングの検証をしたいと思います!
コネクションプーリングするプログラムで100万回リクエストのApache Benchを実行
下記のスクリプトを実行
oracle_pconnect.php
<?php $link = oci_pconnect('system', '[パスワード]', 'xe'); $result = oci_parse($link, "SELECT 1;"); oci_close($link); ?>
Apache Benchの実行
ab -n 1000000 -c 100 http://localhost/oracle_pconnect.php
Apache Benchの実行結果
[root@www html]# ab -n 1000000 -c 100 http://localhost/oracle_pconnect.php
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests
Server Software: Apache/2.2.3
Server Hostname: localhost
Server Port: 80Document Path: /oracle_pconnect.php
Document Length: 0 bytesConcurrency Level: 100
Time taken for tests: 505.614765 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Total transferred: 190001710 bytes
HTML transferred: 0 bytes
Requests per second: 1977.79 [#/sec] (mean)
Time per request: 50.561 [ms] (mean)
Time per request: 0.506 [ms] (mean, across all concurrent requests)
Transfer rate: 366.98 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 5 10.3 1 319
Processing: 0 44 127.2 24 8470
Waiting: 0 33 117.1 12 8460
Total: 0 49 128.9 28 8476Percentage of the requests served within a certain time (ms)
50% 28
66% 58
75% 61
80% 63
90% 83
95% 103
98% 189
99% 455
100% 8476 (longest request)
Time taken for tests: 505.614765 secondsなので、約8分かかりました。
約2倍強処理速度が向上しました。
コネクションプーリングするプログラムで100万回リクエストのApache Benchを実行(接続時キャラクタセットを指定)
下記のスクリプトを実行
oracle_pconnect2.php
<?php $link = oci_pconnect('system', '[パスワード]', 'xe', 'JA16SJIS'); $result = oci_parse($link, "SELECT 1;"); oci_close($link); ?>
Apache Benchの実行
ab -n 1000000 -c 100 http://localhost/oracle_pconnect2.php
Apache Benchの実行結果
[root@www html]# ab -n 1000000 -c 100 http://localhost/oracle_pconnect2.php
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests
Server Software: Apache/2.2.3
Server Hostname: localhost
Server Port: 80Document Path: /oracle_pconnect2.php
Document Length: 0 bytesConcurrency Level: 100
Time taken for tests: 380.586453 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Total transferred: 190000190 bytes
HTML transferred: 0 bytes
Requests per second: 2627.52 [#/sec] (mean)
Time per request: 38.059 [ms] (mean)
Time per request: 0.381 [ms] (mean, across all concurrent requests)
Transfer rate: 487.53 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 8.6 0 297
Processing: 0 33 122.2 5 6322
Waiting: 0 25 114.2 3 6321
Total: 0 37 123.7 6 6325Percentage of the requests served within a certain time (ms)
50% 6
66% 47
75% 52
80% 54
90% 65
95% 87
98% 138
99% 379
100% 6325 (longest request)
Time taken for tests: 380.586453 secondsなので、約6分かかりました。
こちらも約2倍強処理速度が向上しました。
コネクションプーリングをしないMySQL並に速度が向上した結果が出ました。
まとめ
処理速度はやはりMySQLに分がありますね。さすがです。
しかし、無償のOracle Database XEをコネクションプーリングをする事で、同時接続時の処理速度の向上が図れる事がわかりました。
これを知る事・体験する事が出来て良い検証だったなーと思いました。
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
phpを使用してOracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。MySQL編 その3
前回の検証では、コネクションプーリングの利点を理解する事が出来たのですが、Apache Benchでの検証をするとどうなるかというコメントで終了していました。
今回Apache Benchでの検証をしたいと思います。
phpを使用してOracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。MySQL編 - @camelmasaの開発日記
phpを使用してOracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。MySQL編 その2 - @camelmasaの開発日記
mysql_connect関数でSELECTクエリ100万回の速度実験(for文内でMySQLに毎回接続しない場合)
<?php $start = array_sum(explode(" ",microtime())); $link = mysql_connect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); for($i=0;$i<1000000;$i++){ $result = mysql_query("SELECT 1;"); } mysql_close($link); $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
このスクリプトを下記に修正。
mysql_connect2.php
<?php $link = mysql_connect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); $result = mysql_query("SELECT 1;"); mysql_close($link); ?>
上記のコネクションプーリングしないプログラムで100万回リクエストのApache Benchを実行
Apache Benchの実行
ab -n 1000000 -c 100 http://localhost/mysql_connect2.php
Apache Benchの実行結果
[root@www time2]# ab -n 1000000 -c 100 http://localhost/mysql_connect2.php
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests
Server Software: Apache/2.2.3
Server Hostname: localhost
Server Port: 80Document Path: /mysql_connect2.php
Document Length: 1 bytesConcurrency Level: 100
Time taken for tests: 364.58800 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Total transferred: 191000000 bytes
HTML transferred: 1000000 bytes
Requests per second: 2746.81 [#/sec] (mean)
Time per request: 36.406 [ms] (mean)
Time per request: 0.364 [ms] (mean, across all concurrent requests)
Transfer rate: 512.34 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 14.0 0 347
Processing: 0 33 140.2 4 7507
Waiting: 0 25 100.9 3 7486
Total: 0 35 143.5 4 7507Percentage of the requests served within a certain time (ms)
50% 4
66% 9
75% 15
80% 22
90% 99
95% 192
98% 302
99% 394
100% 7507 (longest request)
Time taken for tests: 364.58800 secondsと出力されているので、6分以上かかった事になります。
結構かかりますね。
mysql_pconnect関数でSELECTクエリ100万回の速度実験(for文内でMySQLに毎回接続しない場合)
<?php $start = array_sum(explode(" ",microtime())); $link = mysql_pconnect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); for($i=0;$i<1000000;$i++){ $result = mysql_query("SELECT 1;"); } //mysql_close($link); $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
このスクリプトを下記に修正。
<?php $link = mysql_pconnect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); $result = mysql_query("SELECT 1;"); ?>
for文部分を外して上記のコネクションプーリングをしたプログラムでApache Benchを実行しました。
上記のコネクションプーリングをするプログラムで100万回リクエストのApache Benchを実行
Apache Benchの実行
ab -n 1000000 -c 100 http://localhost/mysql_pconnect2.php
Apache Benchの実行結果
[root@www time2]# ab -n 1000000 -c 100 http://localhost/mysql_pconnect2.php
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests
Server Software: Apache/2.2.3
Server Hostname: localhost
Server Port: 80Document Path: /mysql_pconnect2.php
Document Length: 1 bytesConcurrency Level: 100
Time taken for tests: 195.267289 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Total transferred: 191000000 bytes
HTML transferred: 1000000 bytes
Requests per second: 5121.19 [#/sec] (mean)
Time per request: 19.527 [ms] (mean)
Time per request: 0.195 [ms] (mean, across all concurrent requests)
Transfer rate: 955.22 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 3.4 0 235
Processing: 0 18 43.3 14 2793
Waiting: 0 14 23.2 13 2480
Total: 0 19 43.6 15 2793Percentage of the requests served within a certain time (ms)
50% 15
66% 17
75% 19
80% 20
90% 24
95% 30
98% 61
99% 114
100% 2793 (longest request)
Time taken for tests: 195.267289 secondsと出力されているので、3分以上かかった事になります。
まとめ
コネクションプーリングをした方が約2倍早く終了しました。
http接続等で同時接続が沢山ある時はコネクションプーリングはかなり効果的なのがわかりました。
今後MySQLを使用したアプリケーションを作成する時は、コネクションプーリングも考慮しようと思います。
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
phpを使用してOracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。MySQL編 その2
前回の記事の検証では、いまいちコネクションプーリング自体を理解していない状態での検証でした。
その為、良い結果を出す事が出来ませんでしたので再度挑戦しました。
前回の記事
http://d.hatena.ne.jp/camelmasa/20090225/1235515758
コネクションプーリングの利点が引き出せなかった原因
- ディスク上に書き込みが発生してしまうINSERTクエリを発行していた。
- execでphpを実行した為
id:sh2さんコメント有難う御座います。
また、mixiにてさぁやさんからもご指摘を頂きました。
MySQLコミュニティ
http://mixi.jp/view_bbs.pl?id=40155421&comment_count=2&comm_id=2234
コメントもあったようですが,exec で php プロセスを毎回立ち上げては,pconnect を使ってないのと一緒ですよね
単純に,
for(;;) {
$dbh = mysql_pconnect(...);
}という場合と,
for(;;) {
$dbh = mysql_connect();
mysql_close($dbh);
}のコードで比べてみてはいかがでしょうか?
なるほど。
僕は『スクリプトの実行が終了してもMySQLとの接続が閉じられないということ』という事でexec関数で1万回phpスクリプトを実行してしまいました。そういう意味では無いという事ですね。
さぁやさん有難う御座いました。
さぁやさんのmixi
http://mixi.jp/show_friend.pl?id=379328
前回の反省を踏まえ、スクリプトのSQL部分を、書き込みが発生しないSELECTクエリに変更し、さぁやさんが提供して頂いたソースで検証してみたいと思います。
また、for文内でMySQLに毎回接続しない方法でも検証してみたいと思います。
mysql_connect関数でSELECTクエリ100万回の速度実験(for文内でMySQLに毎回接続)
<?php $start = array_sum(explode(" ",microtime())); for($i=0;$i<1000000;$i++){ $link = mysql_connect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); $result = mysql_query("SELECT 1;"); mysql_close($link); } $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
実行結果
- 137.99708008766
- 127.38695812225
- 141.63528704643
- 133.98114085197
- 142.13206601143
平均130秒程度といった結果でした。
mysql_pconnect関数でSELECTクエリ100万回の速度実験(for文内でMySQLに毎回接続)
<?php $start = array_sum(explode(" ",microtime())); for($i=0;$i<1000000;$i++){ $link = mysql_pconnect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); $result = mysql_query("SELECT 1;"); //mysql_close($link); } $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
実行結果
- 78.858249902725
- 62.917754888535
- 59.676470994949
- 76.271098852158
- 65.784828901291
平均70秒程度といった結果でした。
mysql_connect関数でSELECTクエリ100万回の速度実験(for文内でMySQLに毎回接続しない場合)
<?php $start = array_sum(explode(" ",microtime())); $link = mysql_connect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); for($i=0;$i<1000000;$i++){ $result = mysql_query("SELECT 1;"); } mysql_close($link); $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
実行結果
- 26.621978998184
- 27.744408845901
- 27.353181123734
- 22.033998966217
- 21.772191047668
平均24秒程度といった結果でした。
mysql_pconnect関数でSELECTクエリ100万回の速度実験(for文内でMySQLに毎回接続しない場合)
<?php $start = array_sum(explode(" ",microtime())); $link = mysql_pconnect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); for($i=0;$i<1000000;$i++){ $result = mysql_query("SELECT 1;"); } //mysql_close($link); $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
実行結果
- 21.91073012352
- 28.815995931625
- 21.802286863327
- 26.527863025665
- 24.077289104462
こちらも平均24秒程度といった結果でした。
まとめ
for文内等でMySQLに毎回接続しなくてはいけないケース(どうゆうケースか想定出来ませんが…)php + MySQLでのコネクションプーリングの利点を確認する事が出来ました。
しかし、for文内でMySQLの接続をする必要が無ければ、コネクションプーリングする必要性が無いという結果が出ました。
次こそはphp + Oracle Database XEのコネクションプーリングを検証したいと思います!
[追記]
次回もid:sh2さんやmixiでのさぁやさんからご指摘を頂きab (Apache Bench)によるコネクションプーリングの検証を行いたいと思います。
ご指摘有難うございます。
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
phpを使用してOracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。MySQL編
まず始めに
文章が長くなってしまったので、MySQL編とOracle Database XE編に分けて記事にしたいと思います。
[追記]
コメント欄にてご指摘頂いた件がありますので、下記検証結果は今のところ正しいと言えないかもしれません。
僕がこのように検証しましたという程度で読んで頂けると幸いです。
再度違う方法で検証&報告します。
最近”コネクションプーリング”というのを知りました。
コネクションプーリングとは
データベースにアクセスする時、アクセスのたびに接続(コネクション)を確立するのではなく、あらかじめ一定数のコネクションを確立しておき、それを使い回す手法。データベースアクセスの負荷を減らすために用いられる。
引用元:コネクションプーリング 【connection pooling】 | ソフトウェア用語辞典
http://ew.hitachi-system.co.jp/w/E382B3E3838DE382AFE382B7E383A7E383B3E38397E383BCE383AAE383B3E382B0.html
色々php,mysql関連の本読みましたけど、コネクションプーリングについて触れている本ってあったかな?
コネクションプーリングをウェブで調べてみると賛否両論あるみたいですけども、実際のとこ動作させてみないとわからないもんで。
そこで、phpを使用して、Oracle Database XEとMySQLへのコネクションプーリングの方法・性能を比較しました。
処理性能を比較する方法
まず処理性能を比較する為のスクリプトは、下記の実行時間を表示する標準関数を使用します。
time.php <?php $start = microtime(); for($i=0;$i<10000;$i++){} $end = microtime(); echo "\n".$end - $start; ?>
実行すると
php time.php 0.000884
こんな感じで実行時間が表示されます。
この実行時間で処理性能を比較したいと思います。
参考サイト
http://nakayalog.net/?p=235
まずphp + MySQLを使用してコネクションプーリングを利用する方法を調べました。
mysql_pconnect関数
http://jp2.php.net/manual/ja/function.mysql-pconnect.php
持続的データベース接続についての詳しい説明
http://jp2.php.net/manual/ja/features.persistent-connections.php
mysql_pconnect関数を使用すると、スクリプトの実行が終了してもMySQLとの接続が閉じられないということらしいです。
じゃあ、いつMySQLとの接続が切れるんだって話だけども…。
まあまあ早速実験開始です。
mysql_connect関数でINSERTクエリ1万回の速度実験
mysql_connectデータベースの作成
CREATE DATABASE `mysql_connect` ;
test_tableテーブルの作成
CREATE TABLE `mysql_connect`.`test_table` ( `test_field` INT NOT NULL , PRIMARY KEY ( `test_field` ) ) ENGINE = InnoDB
<?php $link = mysql_connect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); $result = mysql_query("INSERT INTO `mysql_connect`.`test_table` ( `test_field` ) VALUES ( ".$argv[1]." );"); mysql_close($link); ?>
mysql_connect.php用のtime.phpの作成
<?php $start = microtime(); for($i=0;$i<10000;$i++){ exec("php mysql_connect.php $i"); } $end = microtime(); echo "\n".$end - $start; ?>
それでは実行です。
php time.php -0.16822
っておい!マイナスってなんだよ!過去行っちゃいましたよ。
なんでだろーと思って、time.phpを下記に修正してデバッグ。
<?php $start = microtime(); for($i=0;$i<10000;$i++){ exec("php mysql_connect.php $i"); echo microtime()."\n";//ここを追加しました。 } $end = microtime(); echo "\n".$end - $start; ?>
実行結果
0.13497400 1235517635 0.21877200 1235517635 0.30137900 1235517635 0.38148700 1235517635 0.46109300 1235517635 0.51826300 1235517635 0.57506100 1235517635 0.64548400 1235517635 0.72877100 1235517635 0.80903100 1235517635 0.89188100 1235517635 0.97485400 1235517635 0.12529500 1235517636 0.20909600 1235517636 0.29497800 1235517636 0.37752300 1235517636 0.46024800 1235517636 0.54040300 1235517636 0.60471400 1235517636 0.66184100 1235517636 0.71674400 1235517636 0.77201900 1235517636 0.82703400 1235517636 …
なるほど、[コンマ 秒]って事ですね。
では、それ用にtime.phpを下記の様に修正
mysql_connect.php用のtime.phpの作成(修正版)
<?php $start = array_sum(explode(" ",microtime())); for($i=0;$i<10000;$i++){ exec("php mysql_connect.php $i"); } $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
それでは再度実行です。
php time.php 785.43530797958
かなり時間かかりましたね。
InnoDBというのも遅い原因かもしれません。
mysql_pconnect関数でINSERTクエリ1万回の速度実験
データベースとテーブルは先程のを使用します。
<?php $link = mysql_pconnect('localhost', 'root', '[パスワード]'); mysql_select_db('mysql_connect', $link); $result = mysql_query("INSERT INTO `mysql_connect`.`test_table` ( `test_field` ) VALUES ( ".$argv[1]." );"); ?>
mysql_close()を使用した行を削除しただけですが、きちんとコネクションプーリング出きるでしょうか?
mysql_pconnect.php用のtime.phpの作成
<?php $start = array_sum(explode(" ",microtime())); for($i=0;$i<10000;$i++){ exec("php mysql_pconnect.php $i"); } $end = array_sum(explode(" ",microtime())); echo "\n".$end - $start; ?>
それでは実行です。
php time.php 775.68468093872
10秒短くなったけど…少し違う感じがするなあ。
MySQLコネクションプーリングの結果
一応速度の向上を測る事が出来ましたが、微々たる速度向上という結果でした。
php + MySQLでの結果は良い結果は出ませんでしたが、改善方法をお知りの方は教えて下さい!
次のエントリーではphp + Oracle Database XEのコネクションプーリングを検証したいと思います!
[追記]
id:sh2さんからご指摘頂きました!
同じような検証をされたようです。
http://d.hatena.ne.jp/sh2/20081104/
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
MySQLからOracle Database XEへマイグレーションする事が出来るツールOracle SQL Developerを使用してみました。
先月の記事の中では、MySQLとOracle Database XEの使用メモリ数や、プロセスの動作を比較したのですが、MySQLのデータベースやテーブル、データ等をOracle Database XE上で動作させたいなー、となると、データベース設計をし直す等、余計な作業が発生する必要があるのでは無いかと思っていたのですが、MySQLからOracle Database XEへ簡単に移行が出来るツールがありました!
oracleのサイトにありますOracle SQL Developerというツールを使うと簡単にマイグレーション作業をする事ができます。
Oracle SQL Developerのインストール
Oracle SQL Developerは下記URLからダウンロード出来ます。
http://www.oracle.com/technology/global/jp/software/products/sql/sql121/sql121_dl.html
ダウンロードして、Oracle SQL Developerを起動すると、いきなりjavaのパスを入力して下さいと言われたので、JDKをインストールしました。
下記URLからダウンロード
http://download.java.net/jdk6/6u3/promoted/b05/index.html
Windows Offline Installation, Multi-language JDK fileをクリックしてJDKをダウンロードしました。
javaのパスを入力すると下記の画面が表示されました。
(ちなみに僕の環境(Windows XP)だとC:\Program Files\Java\jdk1.6.0_03\bin\java.exeになります。)
Oracle SQL Developerを使用して、MySQL、Oracle Database XEへ接続
インストールしただけでは、MySQLへアクセスする事が出来ないので、Tools > Preferences 画面の、
Database > Third Party JDBC Drivers 画面からJDBC Driverを追加します。
MySQL用のJDBC Driverは下記のサイトからダウンロード出来ます。
http://dev.mysql.com/downloads/connector/j/5.1.html
Add Entryボタンを押して、下記のファイルを指定しました。
C:/Program Files/sqldeveloper/mysql-connector-java-5.1.7/mysql-connector-java-5.1.7-bin.jar
これでMySQLに接続出来るようになりました。
Oracle SQL Developerを使用して、実際にMySQLに接続してみたいと思います。
左上のタブのFile > Newボタンを押して、データベースコネクションを作成します。
画面のOKを押すと下記の画面が表示されました。
MySQLタブをクリックして、入力欄にMySQLへのアクセス情報を入力してTESTボタンを押したところ、
上記のエラーが表示されました。
192.168.11.9(クライアントPC)からは接続出来ないというエラーのようです。
検索すると、下記のページを参考にすると解決できました。
http://dev.mysql.com/doc/refman/4.1/ja/access-denied.html
userテーブルに192.168.11.9を許可するようにデータを追加して、コマンドで mysqladmin flush-privileges -u root -p[パスワード]を実行すると解決し、無事接続できることを確認できました。
localhost以外からMySQLに接続する設定の方法を始めて知りました!
その後、上記のMySQLのデータベースコネクション追加の方法と同じように、oracleのデータベースコネクションを追加しました。(この作業はすんなり出来ました。)
これで、マイグレーションの準備が完了です。
実際にマイグレーションを実行
マイグレーションを実行するには、Migration > Quick Migrationの画面を開きます。
Verifyのボタンを押してマイグレーションが実行出来るかテストした後、Migrateボタンを押すことでマイグレーションを実行する事が出来ます。
おおお!超簡単!
まとめ
JDBC Driverのダウンロード&インストールや、接続するMySQLの設定の変更等でつまずいてしまうところもあったのですが、接続情報を設定するだけで、簡単にマイグレーション作業が出来てしまってびっくりしました。
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/