Memcached って早いのか!?

f:id:hiraoy:20150625205021p:plainf:id:hiraoy:20150207170949j:plain

こんにちは、おにぎりエンジニア平尾です。

この前メインギターを初めて店に調整/修理に出しました。かなり珍しいギターということは知っていたのですが、プレミアがつくようなギターみたいで驚きました。(自慢)修理費高かったですけど。。。

さて今回は、キャッシュシステムを弊社プロダクトにも導入したいな~と思い。超有名なMemcachedを試してみました。

Memcachedとは(wikipedia引用)

Memcachedは、データとオブジェクトをメモリ内にキャッシュすることでデータベースから読み出しを行う回数を減少させ、データベースを用いた Web サイトを高速化するために良く用いられる。

DBから取得したデータに、キー名をつけメモリ内に入れて、次にそのキーで検索時DBに接続する事なく高速にデータを取得できる感じですね。

facebookは数千台規模のMemcachedサーバがあるみたいです。大規模すぎ(笑)

www.publickey1.jp

どれだけ早いのか試してみます。

ではMemcachedMySQLで、比較してみます。試すことは以下となります

・十万件,百万件のレコードをset (MySQLの場合 INSERT)
・十万件,百万件のレコードをget (MySQLの場合 SELECT)

今回はインストール方法は、いくらでもネット上にあるので省略します。

十万件のレコードをset (MySQLの場合 INSERT)

Memcached

<?php
$m = new Memcached();
$m->addServer('localhost', 11211);

$time_start = microtime(TRUE);

for($i = 0; $i < 100000; $i++) {
    $m->set("key_". $i, $i);
}

$time_end = microtime(TRUE);
$time = $time_end - $time_start;

echo $time;

MySQLのテーブル

CREATE TABLE `kvs` (
  `key_name` varchar(256) NOT NULL,
  `val` varchar(1024) NOT NULL,
  PRIMARY KEY (`key_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

MySQL

$db = mysql_connect('localhost', 'root', '');
mysql_select_db('test_db', $db);

$time_start = microtime(TRUE);

for($i = 0; $i < 100000; $i++) {
    mysql_query("INSERT INTO kvs (key_name, val) VALUES ('key_{$i}', {$i});");
}

$time_end = microtime(TRUE);
$time = $time_end - $time_start;

echo $time;
結果【十万件,百万件のレコードをset (MySQLの場合 INSERT) 】
      十万件, 百万件
Memcached 2.05秒  18.04秒
MySQL    8.66秒  90.78秒

約4倍の速度ですね

十万件のレコードをget (MySQLの場合 SELECT)

Memcached

<?php
$m = new Memcached();
$m->addServer('localhost', 11211);

$time_start = microtime(TRUE);

for($i = 0; $i < 100000; $i++) {
    $m->get("key_". $i, $i);
}

$time_end = microtime(TRUE);
$time = $time_end - $time_start;

echo $time;

MySQL

$db = mysql_connect('localhost', 'root', '');
mysql_select_db('test_db', $db);

$time_start = microtime(TRUE);

for($i = 0; $i < 100000; $i++) {
    mysql_query("SELECT val FROM kvs WHERE key_name = 'key_{$i}';");
}

$time_end = microtime(TRUE);
$time = $time_end - $time_start;

echo $time;
十万件のレコードをget (MySQLの場合 SELECT)
      十万件 百万件
Memcached 1.42秒 14.18秒
MySQL 8.90秒 94.50秒

こちらも約4倍くらいの速度です。

まとめ

驚くほどの差はありませんがまあ早いですね。MySQLでJOINを複数したデータを、セットして取得した場合、劇的に変わる場合があるのでやはりすごいなと思います。 JOINしまくってるゴルフ場検索フォームなどから導入していけたらと思っています。

実際使用する場合は、基本的には以下の様に実装するのが基本的な使用法かと思います。

1 Memcached にget
2 キャッシュがない or Memcachedサーバが落ちている場合、DBから取得
3 2,の結果をMemcached にset

では今回のおすすめおにぎりは!
やみつき!焼豚炒飯おむすび これはかなり人気だと思います。

matome.naver.jp