Memcacheはやっぱりすごかった
タグ [
]
- 2007/06/06
森川穣
森川です。恥ずかしながら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
= "TRUNCATETABLE ";check_performance - $db->query($sql);
- $sql
= "INSERTINTO ";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
= "SELECTvalue ";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はレプリケーションしても大丈夫なのだろうか、
コメント
コメントフォーム
トラックバック
最近の記事
- <Symfony Componentsシリーズ(2)> Symfony 2の秘密兵器: Request Handler [2010年03月11日 : 小川雄大]
- <Symfony Componentsシリーズ(1)> オブジェクトをつなぐEvent Dispatcher [2010年03月11日 : 小川雄大]
- Symfony 2のアプリケーション構成を読む [2010年03月04日 : 小川雄大]
- サーバサイドJavaScriptの「node.js」を試してみました [2010年03月03日 : 中川善樹]
- お初の山梨旅行 [2010年02月26日 : 阿部恵]
- OpenVPNで拠点間VPN [2010年02月25日 : 門脇優児]
- OracleでのLIMITの記述あれこれ [2010年02月24日 : 松田惇]
- symfony DoctrineのTIPS その2 [2010年02月18日 : 牧野克俊]
- KeyRemap4MacBookで自分好みにキーをリマッピング [2010年02月15日 : 熊谷裕志]
- 株式会社アシックス社向け、ランナーのためのゲイトアナリシス・ソフトウェアの共同開発 [2010年02月12日 : 小林有佳]



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