2007/06/06
カテゴリ :
Memcacheはやっぱりすごかった
森川です。恥ずかしながらmemcacheを使うくらいならtmpfsとかMySQLのHEAPテーブルを使えばいいじゃん、などと思っていたのですが、今回簡単なベンチマークをやってみて心を入れ替えました。
はい、memcacheは偉大です。すごく速いです。
テストとして10万件のデータをINSERTして、そこから該当するデータを10万件取得します。まずはmemcacheを使用した場合です。
今回はdagレポジトリのRPM版memcachedとソースからインストールしたPHP 5.2.3を使用してpecl installでmemcacheエクステンションをインストールしています。memcachedの設定はデフォルトのままです。
これで以下のスクリプトを実行します。
この場合、結果は以下のようになります。
ほんとどINSERTとSELECTにかかる時間が変わっていないです。この結果をMySQLのHEAPテーブルを使った場合と比較してみます。
memcacheに比べるとずいぶん遅いです。最後にtmpfsとCache_Liteを使った場合、なのですが… tmpfsを使うと、64MBの割り当ての場合10万件ファイルを作成することができませんでした(しかもHEAPテーブルよりも遅い)。
それ以外にもPostgreSQLでテーブルスペースをtmpfsにするとどうなるかをチェックしたりもしてみました。テーブルとインデックスの領域をtmpfsのテーブルスペースに割り当てても、それほど速度が変わらずでした。。トランザクションログの書き込みがあるから当然INSERTは遅いのですが。。
それと、PHPだけでなくてMySQLの場合は直接SQLを流し込んだりもしてみましたが、PHPから実行するmemcacheのパフォーマンスよりも高くなることはありませんでした。
PEAR::DBを使っていたりでオーバーヘッドがあるので、本当のパフォーマンスのチェックではないかもしれません。
ただ、実際に使うであろうスクリプトを考えると、今回のスクリプトに近い結果になると思います。そういう意味ではPDOとか使ったらもうちょっと速くなったかも。ただ、mysqlコマンドで実行してもINSERTに12秒、SELECTで24秒くらいかかっていたのでmemcacheより速くなることは無いと思います。
さらに良いことに複数台でmemcachedを立ち上げると、キーからmemcachedが自動的に値を保存するサーバを決めてくれるようです。さらにfailoverを有効にしておけば、接続できないサーバに保存することになった値を他のサーバに割り振ってくれます。もちろん接続できてるサーバの値には影響がありません。
セッションハンドラとしてもmemcacheを使用できるので、そっちでも使えそう。
欠点を上げるとすると、ロックができないことでしょうか。インクリメンタルな値に関してはincrコマンドがmemcachedに実装されていますが、それ以外のロックが必要な処理はできません。そんなものをmemcacheに保存するのがそもそもの問題なのですが…
#MySQLのHEAPはレプリケーションしても大丈夫なのだろうか、
はい、memcacheは偉大です。すごく速いです。
テストとして10万件のデータをINSERTして、そこから該当するデータを10万件取得します。まずはmemcacheを使用した場合です。
今回はdagレポジトリのRPM版memcachedとソースからインストールしたPHP 5.2.3を使用してpecl installでmemcacheエクステンションをインストールしています。memcachedの設定はデフォルトのままです。
- #
yum install memcached - #
pecl install memcache - #
vi /usr/local/lib/php.ini - extension=memcache.so
を追加 - #
cat /etc/sysconfig/memcached - PORT="11211"
- USER="nobody"
- MAXCONN="1024"
- CACHESIZE="64"
- OPTIONS=""
これで以下のスクリプトを実行します。
- check_mem.php
- $memcache
= new Memcache; - $memcache->addServer("localhost",
11211); - $memcache->flush();
- for
($i = 0; $i < 100000; $i++) { $memcache->set(md5($i), crc32($i), 0, 36000); - }
- check_mem_2.php
- <?php
- $memcache
= new Memcache; - $memcache->addServer("localhost",
11211); - for
($i = 0; $i < 100000; $i++) { $memcache->get(md5($i)); - }
この場合、結果は以下のようになります。
- $
time php check_mem.php - real
0m11.558s - user
0m3.948s - sys
0m2.806s - $
time php check_mem_2.php - real
0m9.599s - user
0m3.203s - sys
0m2.827s
ほんとどINSERTとSELECTにかかる時間が変わっていないです。この結果をMySQLのHEAPテーブルを使った場合と比較してみます。
- テーブル定義
- CREATE
TABLE check_performance( name VARCHAR(32), value VARCHAR(255), PRIMARY KEY(name) - )
TYPE=HEAP;
- check_mysql.php
- include_once
"DB.php"; - $dsn
= "mysql://root@localhost/heap"; - $db
= DB::Connect($dsn); - $sql
= "TRUNCATE TABLE check_performance"; - $db->query($sql);
- $sql
= "INSERT INTO check_performance VALUES (?, ?)"; - $sth
= $db->prepare($sql); - for
($i = 0; $i < 100000; $i ++) { $db->execute($sth, array(md5($i), crc32($i))); - }
- check_mysql_2.php
- <?php
- include_once
"DB.php"; - $dsn
= "mysql://root@localhost/heap"; - $db
= DB::Connect($dsn); - $sql
= "SELECT value FROM check_performance WHERE name = ?"; - for
($i = 0; $i < 100000; $i ++) { $value = $db->getOne($sql, array(md5($i))); - }
- 結果
- $
time php check_mysql.php - real
0m58.172s - user
0m33.034s - sys
0m4.086s - $
time php check_mysql_2.php - real
1m54.113s - user
1m10.043s - sys
0m4.982s
memcacheに比べるとずいぶん遅いです。最後にtmpfsとCache_Liteを使った場合、なのですが… tmpfsを使うと、64MBの割り当ての場合10万件ファイルを作成することができませんでした(しかもHEAPテーブルよりも遅い)。
それ以外にもPostgreSQLでテーブルスペースをtmpfsにするとどうなるかをチェックしたりもしてみました。テーブルとインデックスの領域をtmpfsのテーブルスペースに割り当てても、それほど速度が変わらずでした。。トランザクションログの書き込みがあるから当然INSERTは遅いのですが。。
それと、PHPだけでなくてMySQLの場合は直接SQLを流し込んだりもしてみましたが、PHPから実行するmemcacheのパフォーマンスよりも高くなることはありませんでした。
PEAR::DBを使っていたりでオーバーヘッドがあるので、本当のパフォーマンスのチェックではないかもしれません。
ただ、実際に使うであろうスクリプトを考えると、今回のスクリプトに近い結果になると思います。そういう意味ではPDOとか使ったらもうちょっと速くなったかも。ただ、mysqlコマンドで実行してもINSERTに12秒、SELECTで24秒くらいかかっていたのでmemcacheより速くなることは無いと思います。
さらに良いことに複数台でmemcachedを立ち上げると、キーからmemcachedが自動的に値を保存するサーバを決めてくれるようです。さらにfailoverを有効にしておけば、接続できないサーバに保存することになった値を他のサーバに割り振ってくれます。もちろん接続できてるサーバの値には影響がありません。
セッションハンドラとしてもmemcacheを使用できるので、そっちでも使えそう。
欠点を上げるとすると、ロックができないことでしょうか。インクリメンタルな値に関してはincrコマンドがmemcachedに実装されていますが、それ以外のロックが必要な処理はできません。そんなものをmemcacheに保存するのがそもそもの問題なのですが…
#MySQLのHEAPはレプリケーションしても大丈夫なのだろうか、
コメント
コメントフォーム
トラックバックURI
最近の記事
システム開発エンジニア募集! [2012年02月03日 : 小林有佳]
OpenVPNで細々便利な設定 [2012年01月31日 : 門脇優児]
【iOS】Viewの開発・デバッグに役立つ色々 [2012年01月23日 : 中川善樹]
PHPDocumentorの利用方法まとめ [2012年01月19日 : 笹亀弘]
Google Chart Toolsを使ってサイトマップを描こう! [2011年12月21日 : 志田仁美]
stumpwm設定v2 [2011年12月19日 : 門脇優児]
Mashup Awards 7の授賞式が行われました [2011年12月16日 : 中川善樹]
社員旅行に行きました [2011年12月12日 : 大橋寛子]
iCloud風のアイコンを作成する(Fireworks) [2011年12月07日 : 和田記光]
iScroll4でネイティブに近いスマホ向けHTMLページを作成する [2011年12月02日 : 松田惇]













PECL - APC
http://pecl.php.net/package/APC
ベンチマーク
http://www.tymy.net/~matsu/nucleus/item-910.html
Webベースでのアクセスになりますが、
10万件のINSERT、SELECTに対して、以下のような結果でした。
apc
INSERT: 3.7
SELECT: 1.3
memcache
INSERT: 10.8
SELECT: 9.1
APCのメモリキャッシュはサーバ単体で使うのであれば超高速ですね!単体で動かすのであればこっちのほうがよいですね。
XCache、eAcceleratorとかの結果も知りたいですね。あまり変わらないとは思いますが。
私も使うべきではないと思います(ログイン系の場合)。
http://subtech.g.hatena.ne.jp/miyagawa/20061216/1166264097