4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

例えば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公式ブログには沢山載っている。
時間があれば、良く読んでみたいところだ。

その他参考文献

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?