Riak2にデータを出し入れしてみる

Riakアドベントカレンダー二日目。
データをstoreするにあたり、Riakはbucketとkeyという単位でデータを管理するのが基本だ。

## bucketとkey
valueを示すのがkey。
bucketはkeyの集合。
RESTとErlang Clientの各インタフェースで適当なデータを入れてみる。

まずはREST。
PUTやPOSTを使える。
riak2.0での変更点として、リクエストURLの変更がある。
古いの↓

```Old
POSTは http://localhost:8098/riak/bucket
PUTは  http://localhost:8098/riak/bucket/key
```
新しいの↓

```New
POSTは http://localhost:8098/buckets/mybucket/keys
PUTは  http://localhost:8098/buckets/mybucket/keys/mykey
```
この時Valueはどんなデータでも良い。
JSONももちろんOKだし、Xtra backupでも写真でもOK。

```shell
[vagrant@localhost]$ curl -v -XPUT -d '{"myname":"saisa"}'  http://localhost:8098/buckets/mybucket/keys/name
* About to connect() to localhost port 8098 (#0)
*   Trying ::1... 接続を拒否されました
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8098 (#0)
> PUT /buckets/mybucket/keys/name HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:8098
> Accept: */*
> Content-Length: 18
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 204 No Content
< Vary: Accept-Encoding
< Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
< Date: Mon, 02 Dec 2013 12:40:12 GMT
< Content-Type: application/x-www-form-urlencoded
< Content-Length: 0
<
* Connection #0 to host localhost left intact
* Closing connection #0

[vagrant@localhost riak-erlang-client]$ curl http://localhost:8098/buckets/mybucket/keys/name
{"myname":"saisa"}
```
次にerlang clientの場合。
一日目と同様にしてerlang shellを起動。

```ErlangShell
[vagrant@localhost riak-erlang-client]$ erl -pa ebin/ deps/*/ebin
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.3.1  (abort with ^G)
1>  {ok, Pid} = riakc_pb_socket:start_link("127.0.0.1", 8087).
{ok,<0.33.0>}
2> Account = riakc_obj:new(<<"mybucket_c">>, <<"mykey_c">>, <<"saisa">>).
{riakc_obj,<<"mybucket_c">>,<<"mykey_c">>,undefined,[],
           undefined,<<"saisa">>}
3> riakc_pb_socket:put(Pid, Account).
ok
4> {ok, O} = riakc_pb_socket:get(Pid, <<"mybucket_c">>, <<"mykey_c">>).
{ok,{riakc_obj,<<"mybucket_c">>,<<"mykey_c">>,
               <<107,206,97,96,96,96,204,96,202,5,82,28,202,156,255,126,
                 6,205,22,185,146,193,148,...>>,
               [{{dict,2,16,16,8,80,48,
                       {[],[],[],[],[],[],[],[],[],[],[],[],...},
                       {{[],[],[],[],[],[],[],[],[],[],...}}},
                 <<"saisa">>}],
               undefined,undefined}}
```
erlang shellでの解説を軽くすると、

1. riakに接続：プロセスIDをPid変数に束縛。
2. データ作成：Account変数にデータのオブジェクトを束縛。
3. データ格納：riakプロセスとデータを指定して格納を実行。
4. フェッチ：bucketとkeyを指定して入れたデータが帰ってくるか。

erlnagでは変数は大文字から始まる物のみであり、小文字のはatomと呼ばれる定数のような物として扱われる。
{}はタプルなので、{ok, Pid}だと"ok"というatomとPidという変数のタプルとなる。
パターン照合例外といって、実行に失敗した場合はokアトムが帰ってこないので、例外を検出できる。
erlang的には{error, Reason}とか{faild, Why}みたいにしてcatchしたりする。
あと行末にはドットが必要なので注意。

## Bucket Types
2.0の新機能として、bucketを包含するbucket typesというものがある。
キーの名前空間としてbucketがあるが、そのbucketをまとめて管理する。
bucket数が増えてくるとクラスタ内のネットワークを圧迫するらしく、bucket typesを使うとそれを効率的に制御できるらしい。
bucketと違い、riak-adminコマンドで明示的にtypeを作成し、さらに有効化する必要がある。
作成と有効化の二段構えになっている理由とかも面白いので、Riak Source Code Readingに参加することをお勧めする。
ちなみに、riak2.0で新たに加わった新機能のうちいくつかはbucket typeの作成と有効化が必須になっている。
以下の例もYokozunaから。

```shell
[vagrant@localhost riak]$ rel/riak/bin/riak-admin bucket-type create mytype '{"props":{"search_index":"my_index"}}'
mytype created

[vagrant@localhost riak]$ rel/riak/bin/riak-admin bucket-type list
mytype (not active)

[vagrant@localhost riak]$ rel/riak/bin/riak-admin bucket-type status mytype
mytype has been created and may be activated

young_vclock: 20
w: quorum
small_vclock: 50
search_index: <<"my_index">>
rw: quorum
r: quorum
pw: 0
precommit: []
pr: 0
postcommit: []
old_vclock: 86400
notfound_ok: true
n_val: 3
linkfun: {modfun,riak_kv_wm_link_walker,mapreduce_linkfun}
last_write_wins: false
dw: quorum
chash_keyfun: {riak_core_util,chash_std_keyfun}
big_vclock: 50
basic_quorum: false
allow_mult: true
active: false
claimant: 'riak@127.0.0.1'

[vagrant@localhost riak]$ rel/riak/bin/riak-admin bucket-type activate mytype
mytype has been activated

[vagrant@localhost riak]$ rel/riak/bin/riak-admin bucket-type list
mytype (active)
```

# 参考文献
- http://www.slideshare.net/shino/riak-meetup-3-20131106-riak-meetup3riak20pre5
- https://github.com/basho/yokozuna
- https://github.com/basho/riak_core/blob/develop/src/riak_core_bucket_type.erl
- http://docs.basho.com/riak/2.0.0pre5/dev/references/http/store-object/