世界一を目指す楽天の技術部門から、旬な声をお届けします。

ROMA のコマンド拡張について

»

楽天株式会社 楽天技術研究所 西澤無我

■ はじめに

 こんにちは。楽天株式会社で研究開発をしています西澤無我と申します。ここでは、私どもが開発しています ROMA の紹介や、その ROMA 上の面白い機能(ROMA のコマンド拡張)について説明しようと思います。ROMA は楽天で開発されている Ruby 実装の分散 Key-Value Store です。ROMA の利用者は ROMA に対して、データを set したり get したりすることができます。さらに、ROMA の拡張機能として、利用者が独自に開発したプラグインを ROMA に追加することができます。

 本稿では、まず ROMA の概要について説明をします。その後、ROMA のプラグイン機構について紹介します。そして、その例として、ECHO コマンドを ROMA に追加するコマンド拡張プラグインのコードを示します。

■ ROMA について

 ROMA は楽天で開発されている Ruby 実装の分散 Key-Value Store です。楽天技術研究所のフェローである Ruby 開発者のまつもとゆきひろ氏と共同で研究、開発されています。Key-Value Store とは、Key とそれに関連する Value のペアを高速出し入れするためのデータストアです。ROMA は複数のマシン上に、1つの大きな Key-Value Store を構築するためのソフトウェアです。ROMA の利用者は、1つのハッシュテーブルへアクセスように、ROMA へアクセスできます。

 ROMA は以下の特徴をもつ分散 Key-Value Store です。

  • 高いスケーラビリティ
  • 高い障害耐性
  • Memcached[1]  と互換性のあるプロトコル
  • プラグイン機構で ROMA の拡張が容易

 現在、ROMA のバージョンは0.8.2 です。GitHub でソースコードが公開されています。誰でもソースコードを閲覧することができます [2] 

■ ROMA のプラグイン機構

 多くの Key-Value Store は、上述した ROMA の特徴のいくつか(もしくはすべて)を備えています。ここでは、ROMA 特有のプラグイン機構について紹介します。

 ROMA 本体の振る舞いを変更するために、ROMA はプラグイン機構を提供しています。利用用途に応じて、ソフトウェアの振る舞いを変更したいときがしばしばあります。プラグイン機構とは、ソフトウェアの振る舞いを拡張する方法の1つとして、多くのソフトウェアで提供されています。ソフトウェアの利用者は、ソフトウェアをどのように拡張したいかを1つのモジュールとして、ソフトウェア本体から切り出して記述できます。この拡張モジュールがプラグインです。ソフトウェアは利用者が記述したプラグインを読み込み、その振る舞いを変更します。

 ROMA では、独自のプラグインを Ruby で記述することにより、ROMA を部分的に拡張することができます。ROMA のプラグイン機構とは、ROMA 本体のプログラムに埋め込まれている拡張ポイントのことです。利用者はプラグインを Ruby を使って宣言し、ROMA に読み込ませます。すると、ROMA の本体の拡張ポイントが呼び出されるタイミングで、プラグインで宣言した振る舞いを ROMA にさせることができます。ROMA にプラグインを読み込ませるには、そのプラグインを指定されているディレクトリに配置し、設定ファイルを変更するだけです。

■ ECHO コマンドプラグインのコード例

 このプラグイン機構を利用して、ROMA が受け付けるコマンドを拡張することができます。例えば、以下のソースコードは、簡単な ECHO コマンドを ROMA に追加するためのプラグインです。

module EchoCommand

  include ::Roma::CommandPlugin

  def ev_echo(cmds)

    send_data("#{cmds[1..-1].join(' ')}¥r¥n")

  end

end

 上記の EchoCommand プラグインは Ruby のモジュールです。本モジュールは、Roma::Command::Plugin を include しています。これにより、本モジュールを読み込んだ ROMA 本体は、EchoCommand プラグインがコマンド拡張のためのプラグインであることを理解します。このモジュールを読み込んだ ROMA に対し ECHO コマンドを発行すると、ROMA は受信メッセージの先頭を解析します。”echo” という文字列から始まるメッセージであれば、ROMA は EchoCommand プラグインの ev_echo メソッドを呼び出します。

 ev_echo メソッドを ROMA が呼び出すとき、そのメソッドの引数 cmds には、クライアントが発行した ECHO コマンドの文字列が配列として渡されます。この配列の 0 番目の要素はコマンド名である “echo” です。メソッドの内部では send_data メソッドが呼び出されています。これはクライアントにメッセージを返すメソッドです。引数 cmds の 1 番目以降の配列の要素を連結して、クライアントにメッセージを返します。

 余談ですが、このプラグイン機構を ROMA に追加したとき、真っ先に作ったプラグインが EVAL コマンドのプラグインでした。EVAL コマンドとは、クライアントから送信された文字列を、そのまま ROMA を動かしている Ruby インタープリタが評価実行できるコマンドです。これにより ROMA 本体の振る舞いのいたるところをリモートから修正・変更することができます。いろいろできてしまうので、このコマンドを多用して遊んでいたのですが、そのうちどこをどのように修正・変更したのか自分でも理解ができなくなってしまいました……。そのため、今では EVAL コマンドは、ROMA 本体の標準セットから取り除いています。

■まとめ

 いかがだったでしょうか。ROMA のプラグイン機構によるコマンド拡張について紹介してきました。GitHub 上にある ROMA のソースコードリポジトリには、ROMA に対しリスト操作を行うためのコマンドプラグインなども含まれています。また、ここでは説明し切れない ROMA の拡張機能もあります。もし興味をお持ちの方がいらっしゃいましたら、ぜひ ROMA のソースコードを閲覧して、使っていただければと思います。


[1]]http://memcached.org/

[2]http://github.com/roma/roma/tree

Comment(0)

コメント

コメントを投稿する