Riakアドベントカレンダー二日目。
データをstoreするにあたり、Riakはbucketとkeyという単位でデータを管理するのが基本だ。
bucketとkey
valueを示すのがkey。
bucketはkeyの集合。
RESTとErlang Clientの各インタフェースで適当なデータを入れてみる。
まずはREST。
PUTやPOSTを使える。
riak2.0での変更点として、リクエストURLの変更がある。
古いの↓
POSTは http://localhost:8098/riak/bucket
PUTは http://localhost:8098/riak/bucket/key
新しいの↓
POSTは http://localhost:8098/buckets/mybucket/keys
PUTは http://localhost:8098/buckets/mybucket/keys/mykey
この時Valueはどんなデータでも良い。
JSONももちろんOKだし、Xtra backupでも写真でもOK。
[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を起動。
[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での解説を軽くすると、
- riakに接続:プロセスIDをPid変数に束縛。
- データ作成:Account変数にデータのオブジェクトを束縛。
- データ格納:riakプロセスとデータを指定して格納を実行。
- フェッチ: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から。
[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)