/home/by-natures/dev*

ソフトウェア開発者として働く人の技術的なメモ

(Riak Meetup Tokyo が延期になったので) Riak を勝手にご紹介

[toc]

日本で初めての Riak Meetup が東京で開催される予定だったのですが、雪が降るということで延期になりました。

Riak の開発元である Basho は(たしか)海外の企業なので、海外からわざわざ社員や講演者を呼んでいたことを思うと非常に残念でなりませんが、参加者を思っての延期措置は本当に苦しかったでしょうし、英断だったと思います。「結果として」雪は積もりませんでしたが、雪が降って交通が麻痺しうる状態であれば、フェールセーフに倒すのは正しい選択だと思います。結果だけ見ずに、その結果の過程や裏側で誰が何を考えていたのかを思い馳せられるのは、東京Ruby会議10のスタッフとして参加できたからだと改めて感じました。(レポートはこちら「東京Ruby会議10 でレポートを書いてきました」)。延期された Riak Meetup はこちらから登録できます。日程はまだ決まっていませんが、楽しみですね!

このエントリーでは、機運高まりつつある Riak を、NOSQL 自体の解説も交えてご紹介します。

Riak って何?

一言でいえば、KVS な NOSQL の1つです。KVS で有名な memcached とは異なり、ストレージ上にもデータを格納するためデータは永続化されます。オートシャーディングが強力で、大規模データベースに適しているのも大きな特徴です。実装言語として Erlang を用いているため、元々が大規模分散処理を想定して実装されています。

このエントリでは、そもそも NOSQL や KVS が何なのかを簡単にご紹介して、Riak の特徴に触れてみたいと思います。

NOSQL とは?

[caption id="attachment_2365" align="alignright" width="300"]NOSQLの登場 多くの NOSQL プロダクトが登場しています。[/caption]

簡潔に言えば SQL を利用しないデータベースです。SQL が古いということではなく、SQL では対応できない領域には、その領域に適合した別のデータベースを使おう!という動きが起こっているようです。いわゆるビッグデータという奴ですね。

ビッグデータに対応するには、3つのVが必要とのこと。1つ目は Volume, 膨大な量のデータを捌く必要があります。2つ目に Velocity, 処理の速さが求められます。最後に Variety, データが多様化しているため、これに対応する必要があります。この3つのVを達成するためには、従来の SQL では限界があるため、多くの大規模 Web サービスが NOSQL による解決を試みています。

以前、Greenplum についてご紹介したことがありますが、Greenplum は PostgreSQL を大規模分散処理に向けて構築したプロダクトです。大規模なシャーディングが特徴的ですが、SQL の豊富な機能を兼ね備えたまま大規模対応しているため、その複雑さは相当なものがあります。

一方で NOSQL は、機能は出来る限り削ぎ落して、要所要所で使っていくことが多いです。memcached はデータを永続化せずにメモリ上のみでデータを管理し、KVS という形でのみデータを保持するという制約により、高速でデータを捌く NOSQL です。消えては困るデータには使えないけれど、mixi の足跡機能のように、仮に消えたとしても重大な問題にはならないが、処理速度が求められる場合に用いられます。

CAP 定理と NOSQL

[caption id="attachment_2366" align="alignright" width="300"]CAP定理 (クリックで拡大) CAP定理と NOSQL プロダクトです。C,A,P のうち、2つしか満たせません。
参照元:Visual Guide to NoSQL Systems[/caption]ビッグデータに対応するという背景から、NOSQL の多くは分散システムを構築することができます。分散システムに求められる要件として、CAP 定理が知られています。CAP 定理とは、整合性(Consistency)、可用性(Availability)、分断耐性(Partition Tolerance) の3つのうち、2つしか同時に満たすことができないというものです。分断耐性(P) は分散システムで必須ですから、整合性(C)か可用性(A)のどちらかを捨てることになります。

分断耐性(P)+整合性(C)を求め、ACID 特性を備えたのが GoogleBigtable をはじめ、MongoDB, Memcached, Redis などのデータベースです。システムに障害が発生した場合、処理は1つのノードのみが担当し、他のノードは参照も更新もさせず、整合性(C)を保ちます。

一方で分断耐性(P)+可用性(A)を求め、BASE 特性を備えたのが Dynamo をはじめ、Cassandra, CouchDB, そして今回ご紹介する Riak などのデータベースです。システムに障害が発生した場合でも、稼働できるノードは処理を続けます。その代わりに不整合が起きることも許容する、という立場です。

KVS とは?

KVS についても簡単にご紹介します。KVS とは Key Value Store の略で、Key と Value の対だけを保存する、非常に簡素なデータベースです。SQL で言えば、2つしかカラムがなく、1つのカラムはプライマリキーになっているような状態です。

KVS はそのデータの簡易さから、容易にサーバ台数を増やしてスケールアウトさせることができます。負荷が高くなったら、サーバを増やしてしまえばいいんですね。負荷に応じてサーバ台数を柔軟に変えることができるクラウド技術とも相性がいいです。

オンメモリ KVS (memcached, Redis)

この KVS として有名なのが、memcached です。しかし memcached はメモリ上にのみデータを保持するため、データを永続化させることができません。これを解決したのが Redis という KVS です。Redis はメモリ上にデータを保持しつつ、ストレージにもデータを保持することができます。memcached も Redis も、基本的にはメモリ上でデータを管理するため、オンメモリな KVS と呼ばれます。

ストレージでデータを管理する Riak

一方でオンメモリな KVS は、データ容量がメモリ容量に制約されてしまうという欠点があります。Riak はストレージでデータを管理するため、メモリ容量以上にデータを保持できないオンメモリな KVS の容量制約から解放されます。オンメモリではないため処理速度は犠牲になりますが、データも永続化されますし、KVS なのでスケールアウトもしやすいという特徴を残しています。

スケールアウトしやすいという KVS の特性を生かせば、サーバを増やすごとに総メモリ容量も増えます。どれだけデータを保持しなければならないかを考え、Riak か Redis か(もしくは別のデータベースか)を選ぶ必要があります。

Riak の特徴は?

KVS でデータをストレージで管理する Riak。Key はバイナリデータか文字列、Value は特に制約はないようです。

他の NOSQL との関係が分かったところで、公式HPや公式ドキュメントの「Concepts」で紹介されている Riak の特徴をご紹介します。公式ドキュメントは情報が豊富なので、是非一度ご覧ください。

Availability

高可用性を保持して障害時も読み書き可能と説明があり、分断耐性(P)+可用性(A)を求めて BASE 特性を備えていることが分かります。

[caption id="attachment_2407" align="alignright" width="300"]riak-data-distribution N value が 3 の場合には、3つのノードにデータが書き込まれます。[/caption]Riak はコンシステントハッシュ法を用いた分散クラスタを基礎とする KVS です。マスタノードも存在せず、単体ノードでデータの読み書き応答ができます。データを各ノードで分散させると同時に、1つのデータを複数のノードに書きこむことでデータのレプリケーションも実現しています。Riak では、1つのデータをいくつのノードに書きこむかを N value と呼んでいます。

1つのデータが N 個のノードに書きこまれているため、読み書きの際にいくつのノードから読み書きするかを決めなければなりません。R value は、R 個のノードが応答したら読み込みを成功とする設定です。W value は、W 個のノードの書き込みに成功したら、書き込みを成功とする設定です。

Riak は分断耐性(P)+可用性(A)を求めているとありましたが、この N/R/W value を変更することで、可用性(A)と整合性(C)のバランスを取ることが出来ます。N=R=W の場合は、読み込みも書き込みも全てのノードが成功するまで判断しないので、整合性(C)が強く保たれます。R=W=1 は、1つでもノードが応答すれば、読み込み・書き込みの成功判断をするため、整合性(C)の代わりに可用性(A)が確保されます。詳しくは公式ドキュメントの「Tunable CAP Controls in Riak」をご覧ください。

Fault-Tolerance

ネットワーク分断やハードウェア障害時でも、データを失わないと説明されています。

マスタノードをもたず単体ノードでデータの読み書きが行えることと、N value によるレプリケーション、そして R/W value を N に対して小さく設定することで、Fault-Tolerance を保つことができます。

更に、あるノードがダウンしたことを検知した場合、近隣ノードがそのノードの代わりを務めるように動作する機構(Hinted handoff)も備えています。"Hinted handoff" で検索すると Cassandra の記事が多く出てくるため、Cassandra で有名な機能なのでしょうか。

Operational Simplicity

ノードを追加するときも大きな負荷を強いることなく、簡単に行えると説明がされています。

任意のノードでシェルコマンドを1つ発行するだけでよいのですが、マスタノードが無いので、任意のノードで新しいノードが追加できるのが驚きです。ノードの追加・削除方法については公式ドキュメントの「Adding and Removing Nodes」をご覧ください。

データのアクセス方法については、REST API と Protocol Buffers API の2通りがあります。状況に応じてどちらの API を利用するか選べるのも嬉しいですね。アクセス方法について詳しくは「Basic Requests」をご覧ください。

Scalability

Riak は、クラスタを追加すると自動的にデータを再分配してくれます。パフォーマンスも線形に近い形で上がっていくそうです。Erlang で実装されているのも一役買っているでしょう。

Riak の利用実績

[slideshare id=16264523&doc=yahoojapanriak-130130182004-phpapp02]

Developers Summit 2013 で知ったのですが(参加レポートはこちら)、2013年春から、Yahoo! JAPANAmazon S3 に対抗した新しいクラウドストレージサービスを提供するようです。このストレージ基盤として、Riak が利用されています。

Amazon S3 より常に安価で提供するらしく、運用側はかなり大変そうですが… これだけ大きなサービスの基盤として利用されている Riak の動向に、今後も注目していきたいと思います。

ここで紹介した内容について

ここで紹介した内容について、Riak の公式ドキュメント以外からは上記書籍を参考にしました。

NOSQL の登場や必要性から、様々な NOSQL プロダクトの特徴などを分類し、解説している本です。一冊手元に置いておけば、気になった時にそのプロダクトの特徴を掴むことができるので、私は会社の机の上に置いてあります。みなさんもぜひ参考になさってください。