PFIインターンに行ってきました。

8月1日から8月31日までの1ヶ月間、PFI夏期インターンに行ってきました。

http://preferred.jp/

はてなインターンの 講義・課題・チーム 形式とは趣を異にして、個々人が何か1つのプロジェクトに取り組む方針で進みました。取り組むテーマは 新たに取り組みたい/今取り組んでいる 内容を前提に、既存の問題の中から近いテーマを見つけます(あるいはこじつける^^;)。
インターンの期間中の1ヶ月か2ヶ月の間に成果を出すのが目標!


取り組むテーマはスムーズに決まりました。何か自社で製品を作っていれば普通かと思いますが、探せば問題はいくらでもあるモノです^^
ちなみにPFIの製品は、全文検索エンジンやレコメンドエンジンなどです。


私は以下の4つのプログラムを実装しました:

  • 既存の実装に代わるRPCフレームワーク MessagePack-RPC for PFI
  • クラスタ管理ツール clx
  • プロセス管理ユーティリティ daemonutils
  • key-valueストアを抽象化するライブラリ libkv

MessagePack-RPC for PFI

http://msgpack.sourceforge.jp/
高速なバイナリシリアライズ形式である MessagePack を使ったRPCフレームワークを実装しました。
MessagePack-RPCJSON-RPCを元にしたシンプルなプロトコルで、以下のような特徴があります:

  • 非同期呼び出しができる
  • メッセージの中に型情報が入っている
    • 互換性を保ったまま新しい引数を追加できる
    • 定義ファイルを書かなくてもスクリプト言語から簡単に扱える
  • オーバーヘッドが小さい

MessagePack-RPC は id:tokuhirom さんによるperl版の実装もあります!
kumofs も MessagePack-RPC を使っています。


今回実装したRPCフレームワークPFIの製品と密結合しているので、汎用的にリリースできるものではないのですが、個人的に別の設計のもの(非同期RPCも含む)を作っているので、そちらは近い将来にリリースできそうです。

クラスタ管理ツール「clx」

http://github.com/frsyuki/clx/
複数のサーバーで構成されるクラスタを運用するとき、サーバーの台数が増えると管理が大変になってきます。〜5台程度なら全部手作業でも何とかなりますが、10台を越える前には何か対策を立てておきたいところです。

そこで、複数のサーバーを一括して制御できるようにするシンプルなクラスタ管理ツール clx を実装しました。


clxを使うと複数のサーバーをグループに分けて、同じグループに属するサーバーに対して同じコマンドを実行できます。コマンドは並列して実行されるので、ファイル転送(rsync)のような時間のかかるコマンドでも快適に使えます。
またグループが変更されたタイミングをフックして、サービスを起動したり終了させたりできます。管理者はグループを変更するコマンドを発行するだけで、サーバーの役割を変更できます。


clxの実装はちょっとおもしろい設計になっています。
http://github.com/frsyuki/clx/
clxのコアは汎用的なRPCサーバーで、RPC以外の機能はすべてモジュールとして実装されています。モジュールは起動時に登録できるほか、実行中でも追加でき、RPCを使ってネットワーク越しにモジュールを追加することもできます。


モジュールはclxコアから提供されるモジュールAPIを使って実装されています。利用できるAPIは、

  • RPCメソッドを追加するAPI
  • APIを追加するAPI

の2つだけです。
clxコアを使うとクラスタ管理ツール以外のツールも便利に実装できそうです。


clxはオープンソースで公開しています。Rubyで書かれており、gemでインストールできます:

gem install clx

リポジトリはgithubにあります:http://github.com/frsyuki/clx/

libclx

clx に実装したRPCプロトコルも MessagePack-RPC です。というわけで MessagePack-RPC for PFI を使ってノード一覧やグループなどの情報を取得できるライブラリも実装してきました。

プロセス管理ユーティリティ daemonutils

daemontoolsの簡易版です。プロセスが突然死すると自動的に再起動してくれます。
また自分でデーモン化するコードを書かなくても、起動スクリプトを1つ書くだけで簡単にデーモン化できます。


ポイントはclxと連携できる点です。リモートからデーモンを立ち上げたり状態を取得したりできます。

daemontoolsオープンソースで公開しており、githubからダウンロードできます:http://github.com/frsyuki/daemonutils/

key-valueストアを抽象化するライブラリ libkv

昨今様々なkey-valueストアが出現しています。ぱっと思いつくだけでも、memcached, repcached, Tokyo Cabinet, Tokyo Tyrant, Lux IO, Flare, ROMA, kumofs, ... などなど多種多様です。

そんなkey-valueストアを実行時に切り替えて利用できるC/C++用のライブラリ libkv を実装しました。
サポートしている key-value ストアの実装は、今のところ以下の5種類です:

  • libmemcached
  • Tokyo Cabinet 抽象データベース (tcadb)
  • Tokyo Cabinet ハッシュデータベース (tchdb)
  • Tokyo Cabinet B+木データベース (tcbdb)
  • Tokyo Tyrant (tcrdb)

libkv にはオブジェクトを MessagePack でシリアライズして保存したり、取得したデータを MessagePack でオブジェクトにデシリアライズして返す機能が付いています。
この機能を使うと std::vector や std::map などのオブジェクトを直接引数に渡してkey-valueストアに保存できます。データを取得するときは型チェックもしてくれます。

libkv::tchdb kv;
kv.open("127.0.0.1", 1978);

// pet_obj
std::vector<std::string> vec1;
vec1.push_back("a");
vec1.push_back("b");
kv.put_obj("vec", vec1);

// get_obj
std::vector<std::string> vec2;
kv.get_obj("vec", &vec2);

libkvもオープンソースで公開しました。githubからダウンロードできます:http://github.com/frsyuki/libkv/


http://preferred.jp/