Riakのめも

Riak Meetup Tokyo #3 - connpassでRiakについて勉強してきました。

Riakとは

Bashoが作ったkvs。MapReduceに対応していて、Riak2.0では全文検索ができるようになるらしい。

講演で気になった単語はこんな感じです。

  • key-valueのDB
  • Secondary Index(2i)
  • Map Reduce
  • Counter
  • Full Text Search(Riak2.0)
  • バケットタイプ(Riak2.0)
  • 強い整合性(Riak2.0)
  • セキュリティ(Riak2.0)
  • Stanchon
  • LevelDB
  • APIから操作できる
  • RiakCS(Cloud Storage)

知らないことばかりなので、とりあえず動かしてみることに。

Riakのインストール

UbuntuRHELFreeBSDなど環境に合わせて導入方法がまとまっています。

http://docs.basho.com/riak/latest/quickstart/

CentOSはyumでインストールできるのでその通りコマンドをうつ

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

sudo yum install riak

 インストール完了。簡単!

Riackの起動

riak start

sudo riak start

!!!!

!!!! WARNING: ulimit -n is 1024; 4096 is the recommended minimum.

!!!!

WARNINGでた。。パッと見大丈夫そうなのでとりあえずriak pingで起動確認

riak ping

pong

 pongと出ているので動いている。ちなみに止まってる場合はこうでる。

riak ping

Node 'riak@127.0.0.1' not responding to pings.

 

 クライアントからset、getする

講演中、Erlangだから運用が大変だよってな話があったので、クライアントはErlangだけかと勘違いしてました。
調べてみたらjava,php,python,c,rubyなんでもあります。勘違い恥ずかしい。。

http://docs.basho.com/riak/latest/dev/using/libraries/

使い慣れているphpでクライアントを動かしてみます。

 

gitにphpのクライアントコードがあるので取得

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

 

サンプルをもとに保存と取得のコードを作成
保存用のphp(riaksave.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');

 

$client = new Basho\Riak\Riak('127.0.0.1', 8098);

 

$bucket = $client->bucket('test');

 

$key   = "key_test";

$value = array('test1' => "value1", 'test2' => 10);

 

$person = $bucket->newObject($key, $value);

//$person = $bucket->newObject($key);

//$person->setData($value);

 

$person->store();

取得用のphp(riakload.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');

$client = new Basho\Riak\Riak('127.0.0.1', 8098);

$bucket = $client->bucket('test');

$key = "key_test";

// get value from "key_test" key

$riak_data = $bucket->get('key_test');

echo 'riak_data->data is = ' . var_export($riak_data->data, true) . "\n";

実行してみます。 

php riaksave.php

php riaklead.php

riak_data->data is = array (

  'test1' => 'value1',

  'test2' => 10,

)

 保存と取得ができてます。簡単!!

API経由での利用

Riakの利点の1つAPI経由でkeyの取得を試してみます。

testバケットのkey_testキーの値を取得

curl http://localhost:8098/buckets/test/keys/key_test

{"test1":"value1","test2":10}

 

とれた!!

 

 

サンプルコードを見る限り取得だけでなくAPI経由で保存もできそうな感じです。

 

セカンダリインデックス(2i)

Riakの特徴 2つ目、セカンダリインデックス。

通常のインデックスはテーブルに持たせるものですが、keyにインデックスを持たせる(タグを付けられる)ことができます。(間違っていたらすみません。)

インデックス作成コード(riaksave_index.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');

 

$client = new Basho\Riak\Riak('127.0.0.1', 8098);

 

$bucket = $client->bucket('game');

 

$ps3 = $bucket->newObject("playstation3", array("release" => "20061111"));

// add index

$ps3->addIndex("myindex", "int", 1);

$ps3->addIndex("maker", "bin", "sony");

$ps3->store();

 

$ps4 = $bucket->newObject("playstation4", array("release" => "20140220"));

$ps4->addIndex("myindex", "int", 2);

$ps4->addIndex("maker", "bin", "sony");

$ps4->store();

 

$wii = $bucket->newObject("wiiu", array("release" => "20121208"));

$wii->addIndex("myindex", "int", 3);

$wii->addIndex("maker", "bin", "nintendo");

$wii->store();

 

$xbox = $bucket->newObject("xboxone", array("release" => "2014"));

$xbox->addIndex("myindex", "int", 4);

$xbox->addIndex("maker", "bin", "microsoft");

$xbox->store();

インデックスから取得

curl http://localhost:8098/buckets/game/index/maker_bin/sony

<html><head><title>500 Internal Server Error</title></head><body><h1>Internal Server Error</h1>The server encountered an error while processing this request:<br><pre>{error,{error,insufficient_vnodes_available}}</pre><P><HR><ADDRESS>mochiweb+webmachine web server

エラーが出た。。。 

どうもLevelDBを使う必要があるらしい。

http://docs.basho.com/riak/latest/dev/using/2i/

http://docs.basho.com/riak/latest/ops/advanced/backends/leveldb/

設定を変更

sudo vim /etc/riak/app.config

 83             %% {storage_backend, riak_kv_bitcask_backend},

 84             {storage_backend, riak_kv_eleveldb_backend}, 

設定を反映

sudo riak restart

ok

 あらためてインデックスから取得

curl http://localhost:8098/buckets/game/index/maker_bin/sony

{"keys":["playstation3","playstation4"]}

 今度は取れました。sonyで検索してplaystation3,playstation4がとれています。

今度はphpから

インデックスから取得(riakload_index.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');

 

$client = new Basho\Riak\Riak('127.0.0.1', 8098);

 

$bucket = $client->bucket('game');

 

# Exact Match

echo "===== start exact match =====\n";

$results = $bucket->indexSearch("maker", "bin", "sony");

foreach ($results as $link) {

    $key      = $link->getKey();

    $riakdata = $link->get();

    echo "Key: {$key} , Value: " . var_export($riakdata->data,true) . "\n";

}

 

# Range Search

echo "===== start range search(int) =====\n";

$results = $bucket->indexSearch("myindex", "int", 1, 4);

foreach ($results as $link) {

    $key      = $link->getKey();

    $riakdata = $link->get();

    echo "Key: {$key} , Value: " . var_export($riakdata->data,true) . "\n";

}

 

# Range Search

echo "===== start range search(bin) =====\n";

$results = $bucket->indexSearch("maker", "bin", "sony", "nintendo");

foreach ($results as $link) {

    $key      = $link->getKey();

    $riakdata = $link->get();

    echo "Key: {$key} , Value: " . var_export($riakdata->data,true) . "\n";

}

 

実行(php riakload_index.php

===== start exact match =====

Key: playstation3 , Value: array (

  'release' => '20061111',

)

Key: playstation4 , Value: array (

  'release' => '20140220',

)

===== start range search(int) =====

Key: playstation3 , Value: array (

  'release' => '20061111',

)

Key: playstation4 , Value: array (

  'release' => '20140220',

)

Key: wiiu , Value: array (

  'release' => '20121208',

)

Key: xboxone , Value: array (

  'release' => '2014',

)

===== start range search(bin) =====

Key: wiiu , Value: array (

  'release' => '20121208',

)

Key: playstation3 , Value: array (

  'release' => '20061111',

)

Key: playstation4 , Value: array (

  'release' => '20140220',

)

ちゃんと取得できてます。int型なら範囲指定で取得できるようです。

 

ps4ほしいなぁ。。 

 

資料

 

Riak

Basho Japan | Basho makes Riak, an open source database.

Bashoジャパン主催「Riak Meetup Tokyo」参加レポート - Yahoo! JAPAN Tech Blog(6月くらいのやつ)

Yokozuna: Riak2.0の新しい全文検索機能 // Speaker Deck

 

Riak 2.0 pre5 @ Riak Meetup #3

Riak Meetup Tokyo #3 - connpass

Twitter / Search - #riakjp

Riakのソースコードリーディングがあるみたいです。
Riak Source Code Reading #14 - connpass