Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

PHP+memcache+Repcachedを試してみた

KLabラボから公開されているRepcachedですが、フェイルオーバーした際の挙動とかを確認したくて、サックリ試してみました。
環境はCentOS4.6 on VMwareで仮想NICは1枚、NAT接続でIPアドレスは192.168.98.128です。PHPのバージョンは5.2.5です。
Repcachedのインストールはこんな感じ。

$ wget http://www.monkey.org/~provos/libevent-1.4.2-rc.tar.gz
$ tar zxf libevent-1.4.2-rc.tar.gz
$ cd libevent-1.4.2-rc/
$ ./configure
$ make
$ sudo make install
$ cd ../
$ wget http://downloads.sourceforge.net/repcached/memcached-1.2.2-repcached-1.0.tar.gz
$ tar zxf memcached-1.2.2-repcached-1.0.tar.gz
$ cd memcached-1.2.2-repcached-1.0/
$ ./configure --enable-replication
$ make
$ sudo make install
$

MasterとSlaveの起動は次の通り。Master・Slaveの順です。

$ LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/lib memcached -v -x 127.0.0.1 -l 192.168.98.128
$ LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/lib memcached -v -x 192.168.98.128 -l 127.0.0.1

PECL::memcacheはバージョン3.0.1をpeclコマンドでインストール。

$ sudo pecl install memcache-beta

PHPスクリプトは次の通りです。

<?php
$ttl = 60;
$servers = array(array('ip' => '192.168.98.128', 'port' => 11211),
                 array('ip' => '127.0.0.1', 'port' => 11211));
//$servers = array(array('ip' => '127.0.0.1', 'port' => 11211));


$memcache = new Memcache();

foreach ($servers as $server) {
    $ip = $server['ip'];
    $port = $server['port'];
    if (@$memcache->pconnect($ip, $port)) {
        printf('connected to %s:%s<br/>', $ip, $port);
        break;
    }
}
if (!$memcache->getStats()) {
    die('failed to connect to server');
}

$version = $memcache->getVersion();
echo 'server version: '.$version.'<br/>';

$get_result = $memcache->get('key99');
echo 'cached data:<br/>';
var_dump($get_result);

if (!$get_result) {
    for ($i = 0; $i < 100; $i++) {
        $obj = new stdClass;
        $obj->str = 'test' . $i;
        $obj->int = $i;
        $obj->date = microtime();

        $obj = new Exception('exception' . $i);

        if (!$memcache->set('key' . $i, $obj, false, $ttl)) {
            die ('failed to save data');
        }
    }
    echo 'saved data (TTL=' . $ttl . ')<br/>';
}
var_dump($memcache->getStats());
var_dump($memcache->getExtendedStats());

foreach ($servers as $server) {
    $ip = $server['ip'];
    $port = $server['port'];
    var_dump(@$memcache->getServerStatus($ip, $port));
}

この状態でブラウザから2回アクセスすると次のように表示され、

connected to 192.168.98.128:11211
server version: 1.2.2
cached data:

object(stdClass)[2]
  public 'str' => string 'test99' (length=6)
  public 'int' => int 99
  public 'date' => string '0.27303200 1205831733' (length=21)
            :

ここでMasterをCTRL+Cで落として再度アクセスすると、

connected to 127.0.0.1:11211
server version: 1.2.2
cached data:

string 'O:8:"stdClass":3:{s:3:"str";s:6:"test99";s:3:"int";i:99;s:4:"date";s:21:"0.65095800 1205831864";}' (length=97)
            :

うおっ。serializeされてる。。。そっかー。
ということで、

<?php$get_result = $memcache->get('key99');
echo 'cached data:<br/>';
var_dump(unserialize($get_result));
            :
        if (!$memcache->set('key' . $i, serialize($obj), false, $ttl)) {
            die ('failed to save data');
        }

のように、ちゃんとserializeしてデータを格納しましょう、ということでした。


それはさておき、この後にMasterを起動し、Slave側のコンソールを見ると

replication: marugoto start 100
replication: marugoto owari

と出ました。なぜここだけローマ字。。。w

追記(2008/03/19 16:00)

間違って古いバージョンを試していたようです。最新のRepcached1.2.0については、PHP+memcache+Repcachedを試してみた 再び - Do You PHP はてなを参照してください。

追記2(2008/04/22 00:55)

マルチマスタに対応したRepcached2.0については、PHP+memcache+Repcachedを試してみた みたび - Do You PHP はてなを参照してください。