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


#概要

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

#インストール
##事前準備

事前に必要なパッケージは[こちら](http://d.hatena.ne.jp/perlcodesample/20120828/1346157233)の記事を参考にさせていただきました。
自分の環境には下記が無かったのでインストール。

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

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

[こちら](http://docs.basho.com/riak/latest/ops/building/installing/erlang/#Installing-on-GNU-Linux)を参考に。

すんごい時間かかる

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

ヒマなので待ってる間にErlangについて調べたり。
[これから15分でErlangを始めるための資料](http://blog.overlasting.net/2007-05-09-1.html)

で、インストール

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

##Riakのインストール

[こちら](http://docs.basho.com/riak/latest/ops/building/installing/rhel-centos/)の「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