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のインストール
Ubuntu、RHEL、FreeBSDなど環境に合わせて導入方法がまとまっています。
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なんでもあります。勘違い恥ずかしい。。
使い慣れている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
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";
実行してみます。
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";
}
===== 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ほしいなぁ。。
資料
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
Riakのソースコードリーディングがあるみたいです。
Riak Source Code Reading #14 - connpass