Do You PHP はてブロ

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

TokyoTyrantをざっくり使ってみた

via. mixi engineer blog

なんだか今さら感漂いますが、PHPからTokyoTyrantに繋げてみたのでまとめてみました。

環境

  • CentOS5.2 on VMwarePlayer on CF-R4
  • PHP5.2.6
  • memcache3.0.2β
  • TokyoCabinet1.3.11
  • TokyoTyrant1.1.4

インストール

おきまりのパターン。まずはTokyoCabinetのインストール。

$ wget http://downloads.sourceforge.net/tokyocabinet/tokyocabinet-1.3.11.tar.gz
$ tar zxf tokyocabinet-1.3.11.tar.gz
$ cd ./tokyocabinet-1.3.11/
$ ./configure
$ make
$ sudo make install
$ 

続いてTokyoTyrantのインストール

$ wget http://downloads.sourceforge.net/tokyocabinet/tokyotyrant-1.1.4.tar.gz
$ tar zxf tokyotyrant-1.1.4.tar.gz
$ cd ./tokyotyrant-1.1.4/
$ ./configure
$ make
$ sudo make install
$ 

起動してみる

ポート番号は1978になります。

$ sudo /usr/local/sbin/ttservctl start
$ netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State
tcp        0      0 0.0.0.0:873                 0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:139                 0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:1978                0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:445                 0.0.0.0:*                   LISTEN
tcp        0      0 :::873                      :::*                        LISTEN
tcp        0      0 :::80                       :::*                        LISTEN
tcp        0      0 :::8081                     :::*                        LISTEN
tcp        0      0 :::22                       :::*                        LISTEN
tcp        0      0 :::443                      :::*                        LISTEN
$ 

ttservctlのデフォルト値は次のようになっています。

basedir="/var/ttserver"
port="1978"
pidfile="$basedir/pid"
logfile="$basedir/log"
ulogdir="$basedir/ulog"
ulimsiz="256m"
sid=1
dbname="$basedir/casket.tch#bnum=1000000"
maxcon="65536"

$dbnameの拡張子が「tch」なので、TCHDB(ファイルベースのハッシュデータベース)になるようです。起動したあとに$basedirを覗いてみると

$ ls /var/ttserver/
casket.tch  log  pid
$ 

になっているはず。
ちなみに、TCMDB(オンメモリハッシュデータベース)で起動する場合は次のような感じ。

$ sudo /usr/local/bin/ttserver "*"

mixi engineer blogには


実際にどの型のデータベースが作られるかは、データベースをオープンする際に名前で決めることができます。「*」ならTCMDBが開かれ、・・・

とあったのですが、どうやるんかな?と思ってました。そのまま、「*」なんですね。。。

TokyoTyrantPHP

で、PHPからの接続方法ですが、2通りの方法があります。

PHP+memcache拡張+TokyoTyrant

まずは、memcache拡張を使ったサンプル。Repcachedのテストで使ったコードを削ったものです。

<?php
$ttl = 10;
$ip = '127.0.0.1';
$port = 1978;

$memcache = new Memcache();
if (!@$memcache->pconnect($ip, $port)) {
  printf('failed to connect %s:%s%s', $ip, $port, PHP_EOL);
  exit;
}

$version = $memcache->getVersion();
echo 'server version: ' . $version . PHP_EOL;

$get_result = $memcache->get('key99');
echo 'cached data:' . PHP_EOL;
var_dump(unserialize($get_result));

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

      if (!$memcache->set('key' . $i, serialize($obj), false, $ttl)) {
          die ('failed to save data');
      }
  }
  echo 'saved data (TTL=' . $ttl . ')' . PHP_EOL;
}

で、テスト実行。プログラム実行後にTokyoTyrantを再起動し、データが残ることを確認。

$ tcrmgr vanish localhost
$ tcrmgr list localhost
$ php tokyotyrant.php
server version: 1.1.4
cached data:
bool(false)
saved data (TTL=10)
$ tcrmgr list localhost
key0
key1
key2
:
key98
key99
$ php tokyotyrant.php
server version: 1.1.4
cached data:
object(stdClass)#2 (3) {
["str"]=>
string(6) "test99"
["int"]=>
int(99)
["date"]=>
string(21) "0.81435800 1222933721"
}
$ sudo /usr/local/sbin/ttservctl stop
Stopping the server of Tokyo Tyrant
Done
$ sudo /usr/local/sbin/ttservctl start
Starting the server of Tokyo Tyrant
Done
$ php tokyotyrant.php
server version: 1.1.4
cached data:
object(stdClass)#2 (3) {
["str"]=>
string(6) "test99"
["int"]=>
int(99)
["date"]=>
string(21) "0.81435800 1222933721"
}
$

まあ、ファイルベースなので、当然の結果といえば当然ですが。また、TCMDBだと再起動するとデータは消えちゃいます。これも当然といえば当然ですが。

PHPPEAR::HTTP_Request+TokyoTyrant

REST風なHTTP互換プロトコルを使ったサンプルは次のような感じ。

<?php
error_reporting(E_ALL);
require_once 'HTTP/Request.php';

define('BASE_URL', 'http://localhost:1978/foo');

// create(or replace)
$request = new HTTP_Request(BASE_URL);
$request->setMethod('PUT');
$request->setBody('bar');
if (!PEAR::isError($request->sendRequest())) {
  echo $request->getResponseBody() . PHP_EOL;
  echo '----' . PHP_EOL;
}

// get
$request = new HTTP_Request(BASE_URL);
if (!PEAR::isError($request->sendRequest())) {
  echo $request->getResponseBody() . PHP_EOL;
  echo '----' . PHP_EOL;
}

// delete
$request = new HTTP_Request(BASE_URL);
$request->setMethod('DELETE');
if (!PEAR::isError($request->sendRequest())) {
  echo $request->getResponseBody() . PHP_EOL;
  echo '----' . PHP_EOL;
}

実行結果は次のとおり。

$ tcrmgr vanish localhost
$ tcrmgr list localhost
$ php tokyotyrant02.php
Created

----
bar
----
OK

----
$

まとめ

まあ、「ちゃんと繋げられましたよー」で終わっちゃうわけですがw
ちなみに、id:cocoitiさんも2008-08-13 - 個々一番のHTTP通信でセッション情報を格納するストレージとして使う例を出してます。