読者です 読者をやめる 読者になる 読者になる

Riak 1.0 の Secondary Index を試す

Riak 1.0 における Secondary Index の制限

  • マルチインデックスクエリーがない
  • SQL っぽいクエリー言語がない
  • ソート/ページネーションがない
  • 文字列と数値のみ
  • バックエンド DB は LevelDB のみ

GitHub からソースを取って来てビルドする

重要なのは 1.0 ブランチを使う事です

$ git clone git://github.com/basho/riak.git
$ cd riak
$ git checkout --track origin/1.0
$ make rel

バックエンドデータベースに LevelDB を使うようにする

app.config ファイルの riak_kv セクションの storage_backend を変更する必要があります。

設定を変更する

$ vim rel/riak/app.config
{riak_kv, [
  %% (省略)
  %% bitcask から eleveldb へ変更します
  %% {storage_backend, riak_kv_bitcask_backend},                    
  {storage_backend, riak_kv_eleveldb_backend},
  %% (省略)
  ]
}

これで LevelDB をバックエンドで使うようになります

Riak を起動する

ちょっと場所がわかりにくいですがここで start/stop/reset 出来ます

$ /rel/riak/bin/riak start

サンプルデータの投入

JSON 生だと読みづらいので python -mjson.tool (Python 2.6 以上|simplejson) を使います。
job(string) と age(integer) に Secondary Index を指定してデータを投入する

インデックスはヘッダーで指定します。

"x-riak-index-名_型: 値"

ここでは名前、仕事、年齢を JSON データで突っ込み、key は moriyoshi で、バケットは pyspa です。

$ curl -X PUT \
    -H "x-riak-index-job_bin: programmer" \
    -H "x-riak-index-age_int: 31" \
    -H "Content-Type: application/json" \
    -d '{"name":"moriyoshi","job":"programmer","age":"31"}' \
    http://127.0.0.1:8098/riak/pyspa/moriyoshi

こちらは key が tokibito で、バケットは同じで pyspa です。

$ curl -X PUT \
    -H "x-riak-index-job_bin: programmer" \
    -H "x-riak-index-age_int: 27" \
    -H "Content-Type: application/json" \
    -d '{"name":"tokibito","job":"programmer","age":"27"}' \
    http://127.0.0.1:8098/riak/pyspa/tokibito

まずはバケットとキー指定で取れるかどうか確認

$ curl http://127.0.0.1:8098/riak/pyspa/moriyoshi | python -mjson.tool
{
    "age": "31", 
    "job": "programmer",
    "name": "moriyoshi"
}

次に Secondary Index の job を使って取れるか確認します、URL は "バケット名/index/名_型/eq/値" といった感じです。

$ curl http://127.0.0.1:8098/buckets/pyspa/index/job_bin/eq/programmer | python -mjson.tool
{
    "keys": [
        "moriyoshi", 
        "tokibito"
    ]
}

無事、job に programmer が付いている二人が取れました

最後に年齢を範囲で検索 30 ~ 50 で書くにしてみます。URL は "バケット名/index/名_型/スタート値/ストップ値" といった感じです

$ curl http://127.0.0.1:8098/buckets/pyspa/index/age_int/30/50 | python -mjson.tool
{
    "keys": [
        "moriyoshi"
    ]
}

無事、30 以上の "moriyoshi" だけが取得できました

Erlang クライアントから Secondary Index にアクセスしてみる

GitHub から持ってきてビルドします

$ git clone git://github.com/basho/riak-erlang-client.git
$ cd riak-erlang-client
$ make

起動するときは deps 以下も -pa に指定することを忘れずに

$ erl -pa ebin deps/*/ebin
Erlang R14B03 (erts-5.8.4) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.4  (abort with ^G)
1> {ok, Pid} = riakc_pb_socket:start_link("127.0.0.1", 8087).
{ok,<0.33.0>}
2> riakc_pb_socket:ping(Pid).
pong
3> riakc_pb_socket:get_index(Pid, <<"pyspa">>, <<"job_bin">>, <<"programmer">>).
{ok,[[<<"pyspa">>,<<"tokibito">>],
     [<<"pyspa">>,<<"moriyoshi">>]]}
4> riakc_pb_socket:get_index(Pid, <<"pyspa">>, <<"age_int">>, 30, 50).
{ok,[[<<"pyspa">>,<<"moriyoshi">>]]}

無事 Secondary Index でデータが取得できました。

感想

メタデータに持たせて気軽に引っ張れるのは凄く良いですね

試すこと

大量にデータを持たせて、5ノードとかにした場合の動作を確認してみたい

追記

もう仕様が変わることはなさそうなので、pre を外しました。