P2P分散ストレージ「Cagra」

id:nyaxt氏との共同開発の分散ストレージ「Cagra」(かぐら)のアルファ版をリリースしました。


Cagraは以下のような特徴を持った(目指した)P2P分散ストレージです。

  • Zeroconf
  • マルチマスタでレプリケーションするWrite
  • 高速な分散Read
  • オプションで高速な非同期Write
  • インターネットレベルよりもLANレベルのマシン台数に特化
  • 巨大データサポート
  • 高速イベント駆動システムコール+軽量スレッド
  • 超アジャ〜イルな開発体制


まだα版で全部が実装されているわけではないですが、とりあえず動きます。

Zeroconf

UDPマルチキャストでノードを自動的に発見するので、一切設定ファイルを書かずに動作せることができます。新たにノードを追加しても、自動的に発見・そのままネットワークに組み込まれるので、設定ファイルを常に最新版に維持する手間も必要もなく、お手軽です。
最初にすべてのノードの数やIPアドレスを把握しておく必要もないので、最初は気楽にネットワークを構築しておいても、後から簡単に拡張できます。


実際の使い方はid:takuma104さんのcagraのα版試してみたよ(ちょと使ってみた編)がとても分かりやすいです。ビルドの方法も載っています。(takuma104さん感謝!)


Global File SystemやOCFSなどのクラスタファイルシステムを使ったことがある方ならよーく分かると思われますが、設定ファイルから解放されることによる精神的お手軽感は絶大です。感動的です。


CagraのデーモンはP2Pで相互に接続しています。デーモンのどれか1つにクライアントプログラム(今のところRuby)を使って接続し、データをput/getします。クライアントはCagraデーモンとは別のホストで動かしてもOKで、ストレージサーバー群とクライアントを分離した運用もできます。

マルチマスタでレプリケーションするWrite

データを書き込むとき、複数のノードに同じデータを書き込むことで、ノードが落ちたときでもデータが失われないように信頼性を高めることができます。


このときに何台のノードにレプリケーションさせるかを指定することができ、データの種類に応じて、書き込み速度と記憶容量を優先させるか、信頼性を優先させるかを変えられます。


Cagraはここで要求された数のレプリケーションが成功することを保証し、レプリケーションできなかったらしっかりエラーを返します。逆にこの挙動を外すこともでき、そのときはWriteがどれくらい成功したかを把握することはできませんが、高速なWriteができます。

高速な分散Read

データはDHT(分散ハッシュテーブル)を使って分散保持されており、Read時にはどのノードが目的のデータを持っているのかを高速に見つけられるようになっています。
データが複数のノードにレプリケーションされていれば、自動的に負荷分散します。

IO戦略

epoll(OSによってepoll/kqueue/selectを自動選択)とcoroutine(=Fiber)を組み合わせたIO戦略を採っています。
カーネルから見ればシングルスレッドのイベント駆動で動いているのですが、coroutineを組み合わせることで、スレッドを使ったブロッキングIOをしているようなプログラミングができるようになっています。
カーネルスレッドの切り替えやmutexロックの奪い合いは発生しませんし、プログラミング中にロックを意識する必要もない上に、ブロッキングIOを連続して回しているような自然なプログラミングができるようになっています。


また、Lighttpdにあるような、tmpfsとsendfileを組み合わせた高速なIOも実装できるようなモデルになっています。