PFIインターンに行ってきました。
8月1日から8月31日までの1ヶ月間、PFI夏期インターンに行ってきました。
はてなインターンの 講義・課題・チーム 形式とは趣を異にして、個々人が何か1つのプロジェクトに取り組む方針で進みました。取り組むテーマは 新たに取り組みたい/今取り組んでいる 内容を前提に、既存の問題の中から近いテーマを見つけます(あるいはこじつける^^;)。
インターンの期間中の1ヶ月か2ヶ月の間に成果を出すのが目標!
取り組むテーマはスムーズに決まりました。何か自社で製品を作っていれば普通かと思いますが、探せば問題はいくらでもあるモノです^^
ちなみにPFIの製品は、全文検索エンジンやレコメンドエンジンなどです。
私は以下の4つのプログラムを実装しました:
- 既存の実装に代わるRPCフレームワーク MessagePack-RPC for PFI
- クラスタ管理ツール clx
- プロセス管理ユーティリティ daemonutils
- key-valueストアを抽象化するライブラリ libkv
MessagePack-RPC for PFI
高速なバイナリシリアライズ形式である MessagePack を使ったRPCフレームワークを実装しました。
MessagePack-RPC は JSON-RPCを元にしたシンプルなプロトコルで、以下のような特徴があります:
- 非同期呼び出しができる
- メッセージの中に型情報が入っている
- 互換性を保ったまま新しい引数を追加できる
- 定義ファイルを書かなくてもスクリプト言語から簡単に扱える
- オーバーヘッドが小さい
MessagePack-RPC は id:tokuhirom さんによるperl版の実装もあります!
kumofs も MessagePack-RPC を使っています。
今回実装したRPCフレームワークはPFIの製品と密結合しているので、汎用的にリリースできるものではないのですが、個人的に別の設計のもの(非同期RPCも含む)を作っているので、そちらは近い将来にリリースできそうです。
クラスタ管理ツール「clx」
複数のサーバーで構成されるクラスタを運用するとき、サーバーの台数が増えると管理が大変になってきます。〜5台程度なら全部手作業でも何とかなりますが、10台を越える前には何か対策を立てておきたいところです。
そこで、複数のサーバーを一括して制御できるようにするシンプルなクラスタ管理ツール clx を実装しました。
clxを使うと複数のサーバーをグループに分けて、同じグループに属するサーバーに対して同じコマンドを実行できます。コマンドは並列して実行されるので、ファイル転送(rsync)のような時間のかかるコマンドでも快適に使えます。
またグループが変更されたタイミングをフックして、サービスを起動したり終了させたりできます。管理者はグループを変更するコマンドを発行するだけで、サーバーの役割を変更できます。
clxの実装はちょっとおもしろい設計になっています。
clxのコアは汎用的なRPCサーバーで、RPC以外の機能はすべてモジュールとして実装されています。モジュールは起動時に登録できるほか、実行中でも追加でき、RPCを使ってネットワーク越しにモジュールを追加することもできます。
モジュールはclxコアから提供されるモジュール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/