さて今日はREST API編。今日から三日間は今日のセミナーで離した内容を引っ張れるのでいささか楽であります(スライド)。RESTといってもPUTとかGETとかDELETEしたら終わりだと思ってるアナタ、僕もそう思ってたよ!しかし現実はそんなに甘くない。
PUT
Riakは当然立ち上げた?いえーい常識だね。まずは http://localhost:8098/ping でOKが返ってくることを確認しよう。
$ curl http://localhost:8098/ping
OK
OKがきたかな?OKなら準備OKだ。こんどは サンプル画像その1をダウンロードしてriak.pngという名前で保存しておこう。次にサンプル画像その2を、右クリックからそのままtest_image.jpgという名前で保存しておこう。そして、これらの画像をRiak上に保存だ。
$ curl -X PUT http://localhost:8098/buckets/image/keys/riak.png -H "content-type: image/png" -T riak.png $ $ curl -X PUT http://localhost:8098/buckets/image/keys/test_image.png -H "content-type: image/jpeg" -T test_image.jpg $
さてcurlが面倒なのは成功したかどうかやエラーコードを特に表示しない。なのでそのまま画像をブラウザで開いてみて確認する。
GET
$ open http://localhost:8098/buckets/image/keys/riak.png $ open http://localhost:8098/buckets/image/keys/test_image.png
さて無事に画像は表示されただろうか。
画像はいかがだっただろうか。
今日スベるのが怖くて出せなかったネタ
Siblings
さて、ひと通りご堪能いただけただろうか。実はこのままだと、QuorumとLast write winsというベタなConcurrency control戦略になってしまって別に何の面白みもない。もしクラスタがネットワークセパレーションで真っ二つにされてしまったらそのまま真っ二つになってデータは光錐の向こうへ消えてしまうだろう。並行宇宙の彼方に行って歴史は完全にブランチしてしまう。
別のものになってしまった並行宇宙が再び出会うとき何が起こるのか?それにはVector Clocksというものが鍵になるのでまずは@itawasaのスライドを見ていただきたい。
ちょっと何を言ってるのかわからないかもしれないが耐えて読み進めてほしい。
まずはVector Clocksを使うために、etc/app.configを次のように変更する。つまり riak_core のセクションに次の一行を挿入してほしい。
{default_bucket_props, [{allow_mult, true}]},
デフォルトのapp.configにはdefault_bucket_propsのエントリはないはずなので、躊躇することなく書き加えてほしい。書き加えたら、再起動
$ bin/riak stop && bin/riak start
さてこれでVector Clocksが有効になっているはずだ。とりあえず結果を見ずに二回PUTしてみる
$ curl -X PUT http://localhost:8098/buckets/hoge/keys/hage -d "mama" $ curl -X PUT http://localhost:8098/buckets/hoge/keys/hage -d "papa" $ curl http://localhost:8098/buckets/hoge/keys/hage Siblings: 4nERQIh7u3oNhfgTt9rVHM 5SZllErj501IVtMiUoCy7l
おおお、なんじゃこりゃあSiglingとは英語で兄弟みたいなそういう意味の言葉なので、つまりはこれが並行世界というものなのだろう。ちなみにDELETEを投げつけると無条件で消えてくれたりする。特定のSiblingを見たいときはURLの最後に "?vtag=
$ curl -v http://localhost:8098/buckets/hoge/keys/hage * About to connect() to localhost port 8098 (#0) * Trying 127.0.0.1... * connected * Connected to localhost (127.0.0.1) port 8098 (#0) > GET /buckets/hoge/keys/hage HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5 > Host: localhost:8098 > Accept: */* > < HTTP/1.1 300 Multiple Choices < X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgbsTTyawZTIlMfKkPHf+BRfFgA= < Vary: Accept, Accept-Encoding < Server: MochiWeb/1.1 WebMachine/1.9.2 (someone had painted it blue) < Last-Modified: Wed, 05 Dec 2012 17:24:56 GMT < ETag: "2kbM3DorCQeJGC65A3GwOs" < Date: Wed, 05 Dec 2012 17:26:45 GMT < Content-Type: text/plain < Content-Length: 56 < Siblings: 4nERQIh7u3oNhfgTt9rVHM 5SZllErj501IVtMiUoCy7l * Connection #0 to host localhost left intact * Closing connection #0
結局なにをしたらよいかというと、
X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgbsTTyawZTIlMfKkPHf+BRfFgA=
というのがVector clockなので、こいつを使ってCAS的なことをしようとしているようだ。つまりGETで得られたこれをそのままPUTに渡すことによって、Siblingsの値が変わっていないことを検出する。変わっていなければSiblingsを全て消してPUTされたものを残す。このVclockが一致していないとRiakは500を返すようになっている。あー不思議だ。
$ curl -X PUT http://localhost:8098/buckets/hoge/keys/hage -H "X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgbsTTyawZTIlsfKsJvB5BRfFgA=" --data "外道父" $ curl http://localhost:8098/buckets/hoge/keys/hage 外道父%
これで並行世界はちゃんとひとつの世界に収束したとさ。ちゃんちゃん。
ちなみに
ネットワーク切断なんかでこの並行世界の収束に失敗すると何が起きるかというと別に大したことはなくて消えた兄弟は消えるし、マージされたやつもまた兄弟みたいなそんな感じになります。
まだスコッチ残ってるけど、そんじゃーね。