そこで今回は、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へのアクセスでしたが、クラスタを形成した場合のパフォーマンスなど、今後さらに調査してみたいと思います。