Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@yuukigoodman

Riakで値が衝突したらどうなるのか

例えば2台で構成されたRiakクラスタがあったとして、ちょうどLANケーブルが引きぬかれたタイミングで、それぞれのノードにkeyが同じでvalueが異なる値がコミットされたとする。
その後LANケーブルをさしてクラスタが復旧し、アプリケーションが問い合わせを行うとどうなるのか みたいな話。

同じkeyを入れたらどうなるのか

「ここに書き込んでおけば安心確実」というMasterという名のシングルポイントは、Riakには無い。
とりえあえず全部入れといて、衝突が起きた時はその値をまるっと返す。
これでアプリケーションは衝突が発生したことが分かるので、ある処理で衝突を解決することができる。
それはVector Clocksという、Riak内部での論理的な時計による時間によるものだ。
(実時間を用いたCentral Clock Systemは、同じRiakクラスタ内に属する独立したHWの物理時計がそれぞれ完全に同期していれば、有効だったのかもしれない。)
去年のAdvent Calendarにわかりやすい記事が載っているので参照してほしい。

とりあえずこの記事に沿って手を動かしてみる。
同じbucketsで同じkeyに、異なる値を2つ入れる。
これは冒頭にある、分断されたタイミングで2つのノードに別の値がコミットされ、その後復旧した直後を想定している。

➜  riak git:(a12d5a2)  curl -XPUT http://localhost:8098/buckets/mybucket/keys/mykey -d "data1"
➜  riak git:(a12d5a2)  curl -XPUT http://localhost:8098/buckets/mybucket/keys/mykey -d "data2"
➜  riak git:(a12d5a2)  curl http://localhost:8098/buckets/mybucket/keys/mykey
Siblings:
6Nq2S4gV70XThAnmRyJ8Tj
nLA0G7skzElvkydPZblK

問い合わせを行って返って来たのは、vtagという値だ。
衝突が発生している。
vtagは値そのものではない。
値を取得するためには、RESTの場合はvtagをパラメータとしてGETする。

➜  riak git:(a12d5a2)  curl http://localhost:8098/buckets/mybucket/keys/mykey?vtag=nLA0G7skzElvkydPZblK
data1

➜  riak git:(a12d5a2)  curl http://localhost:8098/buckets/mybucket/keys/mykey?vtag=6Nq2S4gV70XThAnmRyJ8Tj
data2

これでデータを引き出すことができるので、アプリケーションで解決をして完了だ。

ちなみに、シブリングが発生した状態でGETすると、VClockの値を見ることができる。

➜  riak git:(a12d5a2)  curl -v http://localhost:8098/buckets/mybucket/keys/mykey
(中略)
< X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgat3VuWwZTIlMfKMP+kyhm+LAA=
(後略)

アプリケーションによる衝突解決で一つに確定した値で上書きし、その他のデータを消すには、Vclockの値を使う。

➜  riak git:(a12d5a2)  curl -X PUT  http://localhost:8098/buckets/mybucket/keys/mykey \
> -H 'X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgat3VuWwZTIlMfKMP+kyhm+LAA=' -d 'resolved!'
➜  riak git:(a12d5a2)  curl http://localhost:8098/buckets/mybucket/keys/mykey
resolved!

こうして、Riak内は平和に保たれた。

CRDT

Riak2.0では、より強力な衝突解決の機能が導入される予定だ。
CRDTというアルゴリズムに基づくRiakの新機能は、Bucketのデータ型を予め指定しておくとPUTしただけで最新の値に更新される、という画期的なものらしい。
アプリケーションを書くのが更に楽になる。
とても便利!

まとめ

データが「分散している」というのは、RDBのようにはイメージを持ちにくいかもしれない。
アプリケーションの作成には、Riakの特徴を理解したロジックが必要になるかもしれない。
それに必要な概念やコンセプトも、RiakドキュメントやBasho公式ブログには沢山載っている。
時間があれば、良く読んでみたいところだ。

その他参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
4
Help us understand the problem. What are the problem?