P2P分散ファイルシステム

↑のアイディアを閃く前の話↓

昨日のエントリに書いたRUNESの話で、メッセージの送受と高信頼性マルチキャストは、間違いなく実現可能。メッセージの送受は単にRUNESをデーモンとして動かすだけで良くて、後はプラグインがメッセージを受け取るインターフェースと、メッセージを送るAPIがあればOK。高信頼性マルチキャストは、V-FIELDと連携すれば何の問題も無くできる。


実現方法が分からないのが、クラス変数とノード間のロック。変数は全ノードに全データを持たせれば良いとしても、どうやってそれをノード間で同期するか。同期すると言うことは要するにロックに帰着するわけですが、サーバーに依存しないロック方法、またはサーバーがカスケード・フェイルオーバーできるロック方法が必要。さらに用途から考えて、ノードが動的に出て行ったり入ってきたりする。

このような構成をサポートした分散ファイルシステムがあれば、それをバックエンドに使えば良いかなーと思っていたのですが、どうにもそういうモノが見つからない…。

NFS+LifeKeeperはプロプライエタリなのでダメ。GFSとOCFSはデータの保持をやってくれない&ノードの動的な追加ができない(実はできる?)。V-FIELDはデータの保持しかしない&書き込みができない。その他は論文レベルで実装がまだ無い(そのあたりはこの資料(Chordプロトコルを活用したシステム開発の実際)が詳しい)、というわけで、見つからないのです。


サーバーに依存しない分散ロック自体は、OpenDLMという実装があるのですが、どうもこれはノードの動的な追加ができない気がする。(動的な離脱はできる)GFS(RedHat)もOCFS2も実は中でOpenDLMを使っている。




と、ここまでいろいろ調べた結果、どうも分散ファイルシステムをバックエンドに使う方法は現時点ではできない気がするので、別の方法を考える。

まずサーバーをカスケード・フェイルオーバーするのと、サーバーに依存しないでP2Pで行くのと、どっちが楽なのか。


少し考えるとカスケード・フェイルオーバーの方が楽っぽいのだけど、データの保持をどうするかが問題。待機サーバーとアクティブなサーバーとでまったく同じデータを持っていれば良くて、たとえばブロックデバイスレベルでやるなら、DRBDが使えそう…あれ…DRBDはカスケード・フェイルオーバーできないっぽいな…。
DRBDを使わずに、DeviceMapperとNBDを使う?うーん…それはどうなんだ…


ファイルシステムレベルでやるなら…ふとi-notify+rsync+NFS+VRRPという汚い方法が思いつく…これは無いな。完全に同期しないからいろいろ問題が出そう。


…DeviceMapper+NBD+VRRP+NFSと言う方法が最終手段かもしれない。DRBDをあえて使わない点がポイント。待機サーバーとアクティブサーバーの間でのデータの同期は、NBDをDeviceMapperでミラーリングして行う。(Multipathなぞ織り交ぜると面白そうだと思ったけど面白いだけで無意味)フロンとエンドはNFSで、VRRP冗長化する。
バックエンドにDeviceMapper+NBDでフロントエンドにNFSというのは何とも不格好だけど、これをSQLサーバー+レプリケーション(pgpoolとかMySQL Cluster!とか。カスケード・フェイルオーバーができるか怪しい)にするとすごく格好いいな。まぁ実際にはファイルシステムの方が都合が良さそう。(psqlfsとかPgfsなんてPostgreSQLファイルシステムにするなんてモノがあるけど…)



CodaFSはどうやらサーバーの複製を自前でやってくれるらしい。前にCodaは使おうとしたことがあるけど、サッパリ分からなくてあきらめた記憶がある。
設定自体は http://japan.internet.com/linuxtutorial/20030620/1.html あたりを読めば分かりそうだけど、複雑なのはイヤだなぁ。ユーザーランドで走るプログラムが多いのもイヤだ。それだけディストリビューションに依存しやすくなる。(実際NFSもあまり使いたくなくて、9P2000あたりを使いたい)