Rinda and DRb in the Real World

  • Posted by Nick Sieger

http://blog.nicksieger.com/articles/2006/10/21/rubyconf-rinda-in-the-real-world


Speaker: Glenn Vanderburg


Rindaは関将俊さんの開発した分散協調システムです。David GelernterによるLindaがベースとなっています。JavaSpacesに似ていますが、Ruby精神(Spirit)が色濃く出ています。通信には同じく関さんによるDRbを使っています。

Rindaにはいくつかのチュートリアルがありますが、どれも包括的ではなく、現実世界に適用できるものではありません。GlennがRindaを深く追求し始めたことで(Rindaの)弱点が明らかになってきました。

  • Rindaの基本
    • タプルスペースはタプルの「配列」とでも言うべき、概念的な空間です。参加者はタプルをスペースに書き込んだり、(通常、条件を与えることによって)それらを取り出すことができます。
    • タプルは何らかの仕事をするためのリクエストであり、その仕事に対するレスポンスです。
    • RingServerはRindaのタプルスペースを探すためのブロードキャスト/マルチキャストの参照(lookup)サービスです。
    • テンプレートは取り出すべきタプルを見つけるのに使われます。Template#mactchメソッドは、同じ長さをもち、すべてのnilでない要素が===で等しくなることを要求します。
    • 実際のところ、takeメソッドやwriteメソッドの中では通常配列が使われ、暗黙的に適切なオブジェクトに変換されています。

タプルに格納するもの、読み取るものが決まったら、基本的に次にするのはプロトコルの設計です。APIプロトコルを設計する際にそうであるように、それには特別な注意が必要となります。ドキュメントや変更点の展開、プロセスワークフローの設計でも同様ですね。

    • タプルの要素:コマンド/リクエスト、識別子、関連パラメータ/データ。テンプレートは通常コマンドに、あるときはIDにマッチしますが、データにはマッチしません。
    • 文字列はタプルの中で正常に動作します。なぜなら選択の際に正規表現を使うからです。
    • 数値はタプルの中で正常に動作します。なぜなら範囲指定でマッチングするからです。
    • シンボルはうまく動作しません。少なくとも Symbol < String となるまでは。
    • 通信パターンについて。ステータスの問合せなど、同期通信はRindaのアーキテクチャに適しません。
  • 展開

DRbはJavaRMIと違ってcode/behavior(コード/振る舞い?)を直列化しません。これが、タプルのなかでどのようにカスタムオブジェクトを使うか考える際の制約となります。なぜならコードはすべての参加者間で共有され、連帯して更新されるからです。

ただの仮定ですが、グリーンスレッドを使うよりおそらく複数プロセスのほうが、さまざまなアーキテクチャの構成要素(RingServer、タプルスペース、クライアント)に対してより信頼的です。

タプルスペースはSPOF(single point of failure)です。SPOFなプロセスがバックアップを始め、新しいDRb URLをもちそうなタイミングでクラッシュしたならば、それを再発見できるクライアントの中で、タプルスペース周辺のプロキシをもっているのが有用です。

同一サブネット上の複数のRingServerには注意してください。振る舞いは予測不可能となります。望んだタプルスペースを使えないかもしれません。ほかのRingServerがなくなったときに、使っていたタプルスペースもなくなってしまうかもしれません。

DRbには、不揮発性のオブジェクトIDや暗号化された通信、認証といったセキュリティは組み込まれていません。ある状況下ではこれが問題になりえます。

デフォルトでは永続化しません。そのためクラッシュへの備えの追加や、タプルのロストの扱いを考えなければなりません。

トランザクションもありません。そのためリクエスト実行者は、リクエストが実行中なのかロストしてしまったのかわかりません。

Rubyが成熟して露出が増えるにつれ、それまで十分よかったライブラリも再考が必要になるかもしれません。目下、RindaとDRbは2004年の2月から更新されていません。

  • Q&A

Q.write/takeはアトミックですか?
A.はい。タイムアウトした場合、タプルはそのままです。複数のワーカーが同じタプルを取ることはできません。


Q.伝統的なメッセージキューの代わりにこれをどこで使いますか?(車輪の再発明では?)
A.このアーキテクチャのほうが柔軟性があります。この特別な場合には、JMSのバックエンドがあってもRubyのコードからバックエンドへの接続は想定できません。


Q.よく知られた相関的な(correlator)デザインパターンはありますか?
A.マッチングする型が増えすぎないようにするため、レスポンスの型はリクエストの型に紐付けます。リクエストするプロセスが1つだけならば、連番を発生させるのがシンプルです。P2P的な状況では、ホスト名やプロセスIDを使うことで区別できるでしょう。[GUID/UUIDあたりのことを言ってるように聞こえました。]


Q.廃棄されたタプルを把握するために有効期限を使ったことはありますか?
A.いいえ、でも興味深い可能性があると思います。