4月 30

Key-Value型のデータベースを試してみる。

Cassandra」は、
Facebookで開発され、オープンソースとして公開されている。
いまは、Apacheのトップレベルプロジェクト。
導入事例が豊富なので期待。

インストールだけならば手間はかからない。
予め、JavaSDKをインストールして、ログ用ディレクトリと、ライブラリ用ディレクトリを作成するだけ。

今回はPHPで利用したいので、
Thrift というRPCフレームワークをインストールして、インタフェースクラスを生成する必要がある。
Thrift により、PHPやRubyなど多くのプログラム言語で利用可能になる。

インストールは以下に。


環境はVMware Playerで構築。Ubuntu 9.10 Server を簡易インストール。
Apache 2.2.12
PHP 5.2.10

【JavaSDK】
Cassandraをインストールするために必要なのは、JDKだけ(JREでもいいのかも)

http://java.sun.com/javase/downloads/index.jsp

ここからダウンロードしてインストールをすればいい。

今回の環境(Ubuntu Server)では、標準インストールされているOpenJDKをそのまま使った。

【Cassandra】
ダウンロード
http://cassandra.apache.org/ のページから取得しよう。

$ cd /usr/local/src
$ sudo wget http://ftp.kddilabs.jp/infosystems/apache/cassandra/0.6.1/apache-cassandra-0.6.1-bin.tar.gz
$ sudo tar xzvf apache-cassandra-0.6.1-bin.tar.gz -C /usr/local
$ sudo mv /usr/local/apache-cassandra-0.6.1 /usr/local/cassandra

ディレクトリ作成

$ sudo mkdir -p /var/log/cassandra
$ sudo chown -R `whoami` /var/log/cassandra
$ sudo mkdir -p /var/lib/cassandra
$ sudo chown -R `whoami` /var/lib/cassandra

さぁ、起動!

$ cd /usr/local/cassandra
$ sudo bin/cassandra -p /var/run/cassandra.pid

いろいろメッセージが出て、、、
プロンプトに戻ってくる。
この時点で、コマンドラインでの実行が可能なので、cassandra-cli コマンドを使う。

$ sudo bin/cassandra-cli --host localhost --port=9160
cassandra>

となったら、こっちのもん。help と打てばコマンドヘルプが見られる。
「show keyspaces」コマンドで中身を見てみる。

cassandra> show keyspaces
Keyspace1
system

Keyspace1 と system というキースペース(RDBでいうところのデータベースかな)があることが分かる。
できた。
Cassandraを終了する場合は、

$ sudo kill -KILL `cat /var/run/cassandra.pid`

【Thrift】
つぎにThriftのインストール

事前に必要なライブラリ
【参考】http://wiki.apache.org/thrift/GettingUbuntuPackages

$ sudo apt-get install libboost-dev automake libtool flex bison pkg-config g++

ダウンロード
http://incubator.apache.org/thrift/download/ から取得しよう

$ cd /usr/local/src
$ sudo wget http://ftp.kddilabs.jp/infosystems/apache/incubator/thrift/0.2.0-incubating/thrift-0.2.0-incubating.tar.gz
$ sudo tar xzvf thrift-0.2.0-incubating.tar.gz -C /usr/local
$ sudo mv /usr/local/thrift-0.2.0 /usr/local/thrift

インストール

$ cd /usr/local/thrift
$ ./bootstrap.sh
$ ./configure
$ make
$ sudo make install

【PHP-Cassandra】
Thrift で PHP向けインタフェースを作成する。

$ cd /usr/local/thrift/lib/php/src/
$ thrift --gen php /usr/local/cassandra/interface/cassandra.thrift
$ mv ./gen-php ./packages

PHPからのアクセスを確認するために、
Cassandra PHP Wrapper
のラッパークラスとサンプルプログラムを利用させていただく。Thanks!!

ここで提供してくれているラッパークラスを
「CassandraDB.class.php」というファイルで保存
例)/var/www/CassandraDB.class.php (公開フォルダに置かない方がいいけど、とりあえずお試しなので)

「CassandraDB.class.php」の
先頭の定義はThriftのPHP用ライブラリフォルダを指定するよう編集。

$GLOBALS['THRIFT_ROOT'] = '/usr/local/thrift/lib/php/src';

※ このままだと、実行時に問題が発生したので、
How to install Cassandra + Thrift (and why you should care)
を参考にして、
/usr/local/thrift/lib/php/src/transport/TSocket.php を 2箇所修正
(「delete」部分をコメントアウト、「add」部分を追記)
1箇所目

$pre = null;
while (TRUE) {
    $buf = @fread($this->handle_, $len);
// -- delete     if ($buf === FALSE || $buf === '') {
    if ($buf === FALSE) { // ++ add
    $md = stream_get_meta_data($this->handle_);

2箇所目

} else if (($sz = strlen($buf)) < $len) {
    $md = stream_get_meta_data($this->handle_);
// -- delete       if ($md['timed_out']) {
if (true === $md['timed_out'] && false === $md['blocked']) { // ++ add
    throw new TException('TSocket: timed out reading '.$len.' bytes from '.
    $this->host_.':'.$this->port_);

/usr/local/cassandra/conf/storage-conf.xml は、以下のままにした。
(※ 「true」にすると、cassandra-cli が使えなくなったから)

<ThriftFramedTransport>false</ThriftFramedTransport>

storage-conf.xmlの設定にあわせて「CassandraDB.class.php」も修正。

$this->transport = new TFramedTransport($this->socket, 1024, 1024);

の部分は、

$this->transport = new TBufferedTransport($this->socket, 1024, 1024);

でうまくいった。

サンプルは少し改良して、以下のソースで実行した。
(/var/www/cassandraTest.php)

<?php
include_once('/var/www/CassandraDB.class.php');
// Initialize Cassandra
$cassandra = new CassandraDB("Keyspace1");
// Debug on
$cassandra->SetDisplayErrors(true);
// Insert record ("Columns" in Cassandra)
$record = array();
$record["name"] = "Okamoto";
$record["blog"] = "www.curious-eyes.com/blog/shuhei";
if ($cassandra->InsertRecord('Standard2', "Okamoto", $record))
{
    echo "Record (Columns) inserted successfully.\r\n";
}
// Print record
$record = $cassandra->GetRecordByKey('Standard2', "Okamoto");
print_r($record);
?>

実行URL:

http://localhost/cassandraTest.php

出力結果:

Record (Columns) inserted successfully.
Array
(
[blog] => www.curious-eyes.com/blog/shuhei
[name] => Okamoto
)

少し苦労したけど、
これで、使えるようになった。
あとはデータモデルを理解して、実用可否を検証せねば。

コメント欄!

Your Details

Your Comment

Home

About

Archives

Category

Bicycle

このブログを購読する