ひとりでやるRiak Advent Calendar 2012 day10 - PHPクライアント

Will code for food
さて今日はPHPクライアント。2012年の暮れも迫ってきましたね。

PHPというとPEARなどのパッケージ管理から

$ pear install riak

などとすればサクッとRiakクライアントをインストールすることができると思った?残念でした。まだできません。ふつうにGitHubからriak.phpを落としてきて適当なディレクトリに入れれば、それで動くだろう。ちなみにPHPcurlつきでビルドされていなければならない。確認は

$ php -m | grep curl
curl

などとしてcurlと表示されたら成功だ。表示されていない場合は、PHPのマニュアルに従って、curlがEnableされた状態でのPHPのインストールに挑戦してみよう。なあに、簡単で、macportsでlibcurlが入っている場合は

./configure --with-curl=/opt/local

などとするだけでよい。MacOSにもデフォルトで /usr にcurlが入っているが、これを使うと辛い目にあうのでやめた方がよい。あれ、記憶が定かでないけど、どっちがダメだったんだっけ?たしかどっちかはダメなので、リンクに成功した方を使うとよいだろう。

PHPのコード例は簡単だ。

require_once('riak-php-client/riak.php');

# Connect to Riak
$client = new RiakClient('127.0.0.1', 8098);

# Choose a bucket name
$bucket = $client->bucket('test');

# Supply a key under which to store your data
$person = $bucket->newObject('riak_developer_1', array(
    'name' => "John Smith",
    'age' => 28,
    'company' => "Facebook"
));

# Save the object to Riak
$person->store();

# Fetch the object
$person = $bucket->get('riak_developer_1');

# Update the object
$person->data['company'] = "Google";
$person->store();

とするとよい。実際にhttp requestが飛ぶのは最後の行のstoreが呼ばれたときだ。ちなみに、ここでRiakをひたすら叩きまくるループを書いて、2〜3プロセスを並列に動かすと

PHP Fatal error: Uncaught exception 'Exception' with message 'Could not contact Riak Server: http://127.0.0.1:8098/!' in
...

とかいうエラーを吐いてクライアントが死ぬことがあるかもしれない。MacOSだと何の前触れもなく原因不明のまま「Riakは使えない」という結論になりかけるだろう。


だがちょっと待ってほしい。


riak.phpのソースをよく読んでほしい。


このPHPクライアントは非常に出来が悪く、store()の先で毎回curl_initとcurl_exec, curl_closeを繰り返す構造になっている。毎回TCPコネクションを張ったり切ったりしているのだ。PHPのlibcurlまわりのドキュメントを読んでもソケットを使いまわす的なことが書かれているが実際はどうやら使われていないらしく、Redisと同様ソケットのリサイクルをオンにするとこのエラーは出なくなる。サーバー側で

Linux

# echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
# echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

MacOS

sysctl -w net.inet.tcp.msl=1000

これでmslというのを15000に戻すとまた出るので、この設定が悪いことが分かる。いやそもそもクライアントの実装も悪いのだが。こういった問題で、Bashoが提供する公式クライアントに嫌気がさしたなら、3rd partyのクライアントを使うとよい。PBのよい再実装としてはriak-phpだろうと思う(参考)。いま検索してみたところC拡張をそのまま実装したものもあるようだ。

      • -

ちょっと遅くなってしまったが、この記事を書いたのは2012年の14月4日深夜である。