楽天でROMAとfairyの話を聞いてきた
火曜日のHadoopの話に続き、土曜日には「楽天テクノロジーカンファレンス」でROMAとfairyの話を聞いてきました。fairyはようするに楽天版MapReduce、ROMAは楽天版memcached(よりストレージ寄り)という感じのソフトです。
以下、メモ。
レコメンド&パーソナライゼーション(楽天技研 西岡氏)
(emasaka注:これはROMAとfairyのセッションの直前のセッションだけど、関連性が強いので、関連する部分のみ切り出し)
楽天でレコメンデーションをやる場合、規模が膨大という特徴がある。何千万もの会員と2,500万の商品の組み合わせ。その対策として、Locality Sensitive Hashingなどアルゴリズムを改良すると同時に、多数のマシンを組みあわせている。そのために、現時点ではHadoopを使ってMapReduce処理をし、k-meansのクラスタリングや機械学習に導入している。台数に応じてスケールすることが確認できた。「現時点では」というのは、楽天技研ではROMAとfairyを開発しているので、今後使っていきたい。
fairy(楽天技研 増田氏)
よくいわれるように、世の中のデータ量が爆発的に増えている。それに対応する技術を各社が開発している。GoogleはGFSやMapReduceにより、1日20petaバイトを処理しているという。Yahoo!はHadoopの開発に関わり、利用している。Amazonにも、Dynamoという分散key-valueのシステムがある。ベンダーだが、OracleにもCoherenceという製品がある。
そういう楽天のデータや会員数も爆発している。そこで、まつもとゆきひろさんと共同研究してROMA/fairyを開発中。Rubyを使ったソリューション。まつもとさんの「Rubyを大規模に使いたい」という意欲と楽天技研の「大量のデータを効率的に処理したい」という要望が合わさってスタートした。オープンソース化に向けて開発している。
fairyは分散並列処理フレームワークで、分散並列処理を複数のハードウェアで同時並行処理する。特徴(目標)は、3つ。1つめはスケーラブルなこと。マシンを追加すればどんどん計算力を増やせるようにする。将来的にはJRubyにも対応する。
2つめはプログラマフレンドリー。Rubyの生産性を活かし、より自然で簡潔にプログラミングできるようにする。3つめは(リーズナブルな)パフォーマンス。Rubyは速いとはいわれていないが、データをメモリに置いたり、ネットワークの転送量を減らしたりといった工夫をする。
fairyでは、inputからoutputの間を(MapReduceのmapやshuffle、reduceに相当する)多段の「フィルター」で処理する。MapReduceやHadoopで毎度おなじみのワードカウントの例でいうと、「単語: 1」に分解するfmap、単語ごとにグルーピングするgroup_by、グループごとにカウントするsmapで実現できる。group_byのあとは、単語ごとにマシンが分散される。割り当てはfairyがやる。
(ここでMapReduceでいうとSawzallに相当すると思うRubyソースを見せる。require 'fairy'とかある)
フィルタのメソッドは、ブロックの第1引数が入力I/O、第2引数が出力I/O。
fairyには3種類のマシンが関与する。リクエストをサーバーに投げる「クライアント」、分散された処理を実行する「ノード」、ノードの制御やリクエストの受付をする「マスターサーバー」。
また、データは仮装分散ファイルVFile(GFS相当?)に置かれる。1つのデータを分割して配置する。アクセスするときには分散配置の情報を得てから。まだ仕様は固まっていない。
楽天らしい使い方でいうと、併買データを処理する場合、実際のデータは数千万件×数千万件のかけあわせになる。そこで、購買アイテムの全組み合わせを作るfmapと、組み合わせごとに分解するgroup_by、集計するsmapで処理できる。
ただし現状のfairyは、基本的な処理は実装して動作するものの、実データでの検証とパフォーマンスチューニングはこれから。
ROMA(楽天技研 西沢氏)
ROMA開発の背景として、大量のデータを格納できる基盤システムの必要性がある。大量のトラフィックに耐え、耐障害性のあるもの。
データベースはディスクI/Oがボトルネックになる。かといって、データをメモリ上に置くと、速いが量を置けないし、障害で消失する危険性がある。
ROMAでは高負荷でも高速アクセスでき、データを消失しないシステムを狙った。
特徴は、複数のマシンから構成されるオンメモリストレージで、インターフェイスはkey-valueのハッシュテーブル。クライアントAPIを利用してアクセスするようになっていて、現在JavaとRubyに対応。開発者に分散を意識させない。
分散配置により、データアクセスが集中化してボトルネックになるようなことがないようにする。データは多重化して障害による消失を回避する一方、データの一貫性を重視する(memcachedとの違い)。また、動的にマシン(ノード)を追加できる。
アーキテクチャはP2Pで、各ノードが自律的に状態(ノードの追加やダウン)を管理する。ノード間は環状のモデルで接続される。
ノードはユニークなID(ハッシュ値)を持つ。クライアントが読み書きするときには、まずハッシュ値を計算して担当ノードを割り出し、担当ノードにアクセスするようになっている。パフォーマンスのために、データの探索はサーバー側ではなくクライアントがやる。クライアントは最初に環の情報を全部取得するようになっている。
データが書き込まれるときは、担当ノードが自動的に左右(ハッシュ値の近さで)のノードに対してレプリケートする。一貫性を保つため、セカンダリーにデータが転送されるまでクライアントは待つ。
ROMAへノードの追加するときは、まずノードのマシン上でROMAのプロセスを起動する。すると、自分のハッシュ値を計算し、ブロードキャストする。それを受けて、近いハッシュ値のノードや、メモリの少ないノードが、新ノードにアプローチする。アプローチが早い順に、その隣に参加する。
各ノードには、p(自分の担当データ)、ls(左ノードのデータ)、rs(右ノードのデータ)の3つのデータ領域がある。新しいノードが追加されると、まずlsとrsをコピーしてきてリハッシュ、これで環に所属する。あとはじわじわ環全体に所属情報が伝わる。
今後の課題。データを永続化をしてディスクに保存し、障害時のリカバリーに使う技術を考えている。
また、パフォーマンスチューニングも重要。たとえば、RubyのGCにかかるオーバーヘッドが問題なので、解消したい。案としては、Rubyの拡張ライブラリとして実装して、そこにデータを格納し、メモリは自主管理するというの考えもある。パフォーマンス面では、パフォーマンスと一貫性はトレードオフなので、さまざまなモデルを追加し、アプリケーションによって、一貫性をゆるめてパフォーマンスをあげることもできるようにすることも考えている。
オープンソース化は、来年の予定。ソースを公開するだけではなく、大規模処理や高速化についての知見(GCとパフォーマンスなど)をRubyコミュニティに還元したい。
コメント
コメントの投稿
トラックバック
http://emasaka.blog65.fc2.com/tb.php/506-1918c551
