PHP
Erlang
CentOS
riak

Riak1.4の導入からPHPとの疎通確認までを検証した(CentOS6)

More than 3 years have passed since last update.

概要

「1.4」に特に意味はないです。
この記事を書いたときの最新だったというだけです。
key-key-valueなKVSに興味を持ったので、Riakを検証してみました。
インストール〜PHPとの疎通確認まで。

インストール

事前準備

事前に必要なパッケージはこちらの記事を参考にさせていただきました。
自分の環境には下記が無かったのでインストール。

$ sudo yum -y install ncurses-devel
$ sudo yum -y install autoconf

Erlang(アーラン)のインストール

こちらを参考に。

すんごい時間かかる

$ mkdir erlang && cd erlang
$ wget "http://www.erlang.org/download/otp_src_R16B01.tar.gz"

ヒマなので待ってる間にErlangについて調べたり。
これから15分でErlangを始めるための資料

で、インストール

$ tar zxvf otp_src_R16B01.tar.gz
$ cd otp_src_R16B01
$ ./configure && make && sudo make install

Riakのインストール

こちらの「For Centos 6 / RHEL 6」の項を参考に、
bashoのyumリポジトリを使用してインストールする。

$ sudo yum -y install http://yum.basho.com/gpg/basho-release-6-1.noarch.rpm
$ sudo yum -y install riak

バージョン確認

$ riak version
1.4.7

入ったっぽい

Riakの起動

$ sudo riak start
!!!!
!!!! WARNING: ulimit -n is 1024; 4096 is the recommended minimum.
!!!!

Riakとの疎通確認

$ riak ping
pong

PHPからRiakに接続してみる

riak-php-clientのインストール

bashoに上がったものがあったので、これを使ってみようと思います。
https://github.com/basho/riak-php-client

$ git clone git://github.com/basho/riak-php-client.git

curlが必要なので確認。(入ってなかったら入れましょう)

$ php -m | grep curl
curl

サンプルコード

Riakは特に設定していなければ、8098番ポートで立ち上がるようです。
githubのREADMEにサンプルが上がっているのでそちらを使ってみます。
ここでは最後に下記一部んを追記し、Riakにストアした内容を出力してみます。

print_r($bucket->get('riak_developer_1'));
RiakTest.php
<?php

require_once('riak-php-client/src/Basho/Riak/Riak.php');
require_once('riak-php-client/src/Basho/Riak/Bucket.php');
require_once('riak-php-client/src/Basho/Riak/Exception.php');
require_once('riak-php-client/src/Basho/Riak/Link.php');
require_once('riak-php-client/src/Basho/Riak/MapReduce.php');
require_once('riak-php-client/src/Basho/Riak/Object.php');
require_once('riak-php-client/src/Basho/Riak/StringIO.php');
require_once('riak-php-client/src/Basho/Riak/Utils.php');
require_once('riak-php-client/src/Basho/Riak/Link/Phase.php');
require_once('riak-php-client/src/Basho/Riak/MapReduce/Phase.php');

# Connect to Riak
$client = new Basho\Riak\Riak('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();

print_r($bucket->get('riak_developer_1'));

実行結果

$ php RiakTest.php 
Basho\Riak\Object Object
(
    [meta:protected] => Array
        (
        )

    [indexes:protected] => Array
        (
        )

    [autoIndexes:protected] => Array
        (
        )

    [client] => Basho\Riak\Riak Object
        (
            [host] => 127.0.0.1
            [port] => 8098
            [prefix] => riak
            [mapred_prefix] => mapred
            [indexPrefix] => buckets
            [clientid] => php_5oudvv
            [r] => 2
            [w] => 2
            [dw] => 2
        )

    [bucket] => Basho\Riak\Bucket Object
        (
            [client] => Basho\Riak\Riak Object
                (
                    [host] => 127.0.0.1
                    [port] => 8098
                    [prefix] => riak
                    [mapred_prefix] => mapred
                    [indexPrefix] => buckets
                    [clientid] => php_5oudvv
                    [r] => 2
                    [w] => 2
                    [dw] => 2
                )

            [name] => test
            [r] => 
            [w] => 
            [dw] => 
        )

    [key] => riak_developer_1
    [jsonize] => 1
    [headers] => Array
        (
            [http_code] => 200
            [x-riak-vclock] => a85hYGBgzGDKBVIcypz/fga9jFuYwZTIlcfKkH4/9gxfFgA=
            [vary] => Accept-Encoding
            [server] => MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
            [link] => </riak/test>; rel="up"
            [last-modified] => Wed, 29 Jan 2014 20:24:07 GMT
            [etag] => "7IDLX1QqwPX3YrVmAuOlJI"
            [date] => Wed, 29 Jan 2014 20:24:07 GMT
            [content-type] => application/json
            [content-length] => 49
        )

    [links] => Array
        (
        )

    [siblings] => 
    [exists] => 1
    [data] => Array
        (
            [name] => John Smith
            [age] => 28
            [company] => Google
        )

)

Riakへの登録、Riakからのデータ取得が正常にできたようです。
このサンプルの場合、バケット、キー、値の関係は下表のようになります。

バケット キー
test riak_developer_1 Johon Smith氏のデータ

実験

「値」の部分の配列のネストを深くしてみる

RiakTest2.php
<?php

require_once('riak-php-client/src/Basho/Riak/Riak.php');
require_once('riak-php-client/src/Basho/Riak/Bucket.php');
require_once('riak-php-client/src/Basho/Riak/Object.php');
require_once('riak-php-client/src/Basho/Riak/StringIO.php');
require_once('riak-php-client/src/Basho/Riak/Utils.php');

// Riakに接続
$client = new Basho\Riak\Riak('127.0.0.1', 8098);

// 登録先バケット
$bucket = $client->bucket('test');

$data = array(
    'name'   => 'Taro',
    'status' => array(
        'age'     => 85,
        'company' => 'MTL',
        'blogs'   => array(
            '0' => 'wordpress',
            '1' => 'qiita',
        ),
    ),
);

// 保存用データを生成
$person = $bucket->newObject('custom_developer', $data);

// データを保存
$person->store();

// 結果を出力
var_dump($bucket->get('custom_developer')->data);

実行結果

$ php RiakTest2.php 
array(2) {
  ["name"]=>
  string(4) "Taro"
  ["status"]=>
  array(3) {
    ["age"]=>
    int(85)
    ["company"]=>
    string(3) "MTL"
    ["blogs"]=>
    array(2) {
      [0]=>
      string(9) "wordpress"
      [1]=>
      string(5) "qiita"
    }
  }
}

正常に登録できました。
ちなみにageの部分だけintで登録してみましたが、データ型も保持されているように見えます。

シリアライズした文字列を登録してみる

まあRiakではあまりやらない気もしますが。
PHPSerializeに変換した文字列を突っ込めるか試してみます。

RiakTest3.php
<?php

require_once('riak-php-client/src/Basho/Riak/Riak.php');
require_once('riak-php-client/src/Basho/Riak/Bucket.php');
require_once('riak-php-client/src/Basho/Riak/Object.php');
require_once('riak-php-client/src/Basho/Riak/StringIO.php');
require_once('riak-php-client/src/Basho/Riak/Utils.php');

// Riakに接続
$client = new Basho\Riak\Riak('127.0.0.1', 8098);

// 登録先バケット
$bucket = $client->bucket('test');

$data = array(
    'name'   => 'Taro',
    'status' => array(
        'age'     => 85,
        'company' => 'MTL',
        'blogs'   => array(
            '0' => 'wordpress',
            '1' => 'qiita',
        ),
    ),
);

// 保存用データを生成
$person = $bucket->newObject('custom_developer2', serialize($data));

// データを保存
$person->store();

$result = $bucket->get('custom_developer2')->data;

// 結果出力
var_dump($result);
var_dump(unserialize($result));

実行結果

$ php RiakTest3.php 
string(140) "a:2:{s:4:"name";s:4:"Taro";s:6:"status";a:3:{s:3:"age";i:85;s:7:"company";s:3:"MTL";s:5:"blogs";a:2:{i:0;s:9:"wordpress";i:1;s:5:"qiita";}}}"
array(2) {
  ["name"]=>
  string(4) "Taro"
  ["status"]=>
  array(3) {
    ["age"]=>
    int(85)
    ["company"]=>
    string(3) "MTL"
    ["blogs"]=>
    array(2) {
      [0]=>
      string(9) "wordpress"
      [1]=>
      string(5) "qiita"
    }
  }
}

こちらも特に問題なく。

とりあえずここまで。
Bucketという単位が使える点でRDBをキャッシュするのには使いやすそう、という印象でした。
柔軟にデータを扱える分、データ設計をきっちりやらないとバケットの中がカオスになりそうですがw