そこで今回は、Cassandraにphpからアクセスしてみたいと思います。
CassandraにphpからアクセスするためのAPIライブラリとして以下のようなものがあるようです。
このうち、Thriftは、Cassandra専用でもPHP専用でもなく、複数の言語間でRPC通信を可能にする汎用フレームワークで、設定コードを元に各言語用のプログラムを生成します。他のライブラリはThriftで生成されたCassandraのlow-level APIをラップしたものになります。
もともとThriftを使おうと思っていましたが、Thriftの最新版 0.8.0は、Cassandra1.1.5では出力されたコードが不十分だったため、一度断念しました。機会があれば再度試してみたいと思います。
今回はphpcassaを試してみました。
phpcassaもThriftを使用しているので、Thriftが組み込まれ、すでにコード生成もされているので、インストールも非常に簡単です。
それでは早速インストールしてみます。
$ cd /usr/local/src $ wget https://github.com/downloads/thobbs/phpcassa/phpcassa-1.0.a.5.tar.gz $ tar xzvf phpcassa-1.0.a.5.tar.gz $ cd phpcassa-1.0.a.5 $ phpize $ ./configure $ make # make install
これでインストールは完了です。
次にアプリケーション用ディレクトリを作成し、phpcassaのライブラリをコピーします。
$ mkdir -p /home/memorycraft/app $ cd /usr/local/src/phpcassa-1.0.a.5 $ cp -r lib /home/memorycraft/app/ $ cd /home/memorycraft/app/ $ touch test.php $ tree -L 2 . |-- lib | |-- autoload.php | |-- phpcassa | `-- thrift `-- test.php
これでライブラリがそろったので、これらを利用してcassandraにアクセスするコードを書いてみます。
$ vim test.php
<?php
require(dirname(__FILE__).'/lib/autoload.php');
use phpcassa\ColumnFamily;
use phpcassa\ColumnSlice;
use phpcassa\Connection\ConnectionPool;
try{
$servers = array('localhost:9160');
$pool = new ConnectionPool('Hogebook', $servers);
$user = new ColumnFamily($pool, 'User');
//データの挿入
$user->insert('memorycraftgirl',
array(
'email' => 'ng@gmail.com',
'gender' => 'female',
)
);
//データの更新
$user->insert('memorycraftgirl', array('email'=>'memorycraft+girl@gmail.com'));
//キーで全カラムを取得
$girl = $user->get('memorycraftgirl');
echo 'girl = ' . print_r($girl, true);
//キーでカラムを指定して取得
$email = $user->get('memorycraftgirl', null, array('email'));
echo 'email = ' . print_r($email, true);
//複数キーを指定して取得
$users = $user->multiget(array('memorycraft', 'memorycraftgirl'));
echo 'users = ' . print_r($users, true);
//カラムの削除
$user->remove('memorycraftgirl', array('email'));
echo 'girl after remove column = ' . print_r($user->get('memorycraftgirl'), true);
//行の削除
$user->remove('memorycraftgirl');
echo 'girl after remove row = ' . print_r($user->get('memorycraftgirl'), true);
$pool->close();
}
catch(Exception $e){
echo 'ERROR : ' . print_r($e, true);
}
?>
このコードでは前回作成したHogebookのUserというColumn Familyに対して、挿入/更新/取得/削除を行い、その都度結果や、Column Familyの状態を表示するようにしました。
それでは実行してみます。
$ php test.php
girl = Array
(
[email] => memorycraft+girl@gmail.com
[gender] => female
)
email = Array
(
[email] => memorycraft+girl@gmail.com
)
users = Array
(
[memorycraft] => Array
(
[email] => memorycraft@gmail.com
[gender] => male
)
[memorycraftgirl] => Array
(
[email] => memorycraft+girl@gmail.com
[gender] => female
)
)
girl after remove column = Array
(
[gender] => female
)
ERROR : cassandra\NotFoundException Object
(
[message:protected] =>
[string:Exception:private] =>
[code:protected] => 0
[file:protected] => /home/memorycraft/app/lib/phpcassa/ColumnFamily.php
[line:protected] => 308
[trace:Exception:private] => Array
(
[0] => Array
(
[file] => /home/memorycraft/app/lib/phpcassa/ColumnFamily.php
[line] => 299
[function] => _get
[class] => phpcassa\ColumnFamily
[type] => ->
[args] => Array
(
[0] => memorycraftgirl
[1] => cassandra\ColumnParent Object
(
[column_family] => User
[super_column] =>
)
[2] => cassandra\SlicePredicate Object
(
[column_names] =>
[slice_range] => phpcassa\ColumnSlice Object
(
[start] =>
[finish] =>
[reversed] =>
[count] => 100
)
)
[3] =>
)
)
[1] => Array
(
[file] => /home/memorycraft/app/test.php
[line] => 43
[function] => get
[class] => phpcassa\ColumnFamily
[type] => ->
[args] => Array
(
[0] => memorycraftgirl
)
)
)
[previous:Exception:private] =>
)
概ね期待通りの動作になっています。
また、存在しないキーを取得しようとすると例外が返る仕様のようです。
前回少し触れましたが、Cassandraはメモリテーブルを使用するため、このテストプログラムを実行したときの感覚としてはmemcacheへアクセスしたときと同じような体感速度でした。
今回は、localhostへのアクセスでしたが、クラスタを形成した場合のパフォーマンスなど、今後さらに調査してみたいと思います。