非同期で全文検索エンジンgroongaを叩く AnyEvent::Groonga 書いたよ
要するにAnyEventでgroongaを使いたかったのでperlモジュール書きました。んでもって久々にCPANにアップしましたよ、という告白です。
AnyEvent::Groonga - Groonga client for AnyEvent
http://search.cpan.org/~miki/AnyEvent-Groonga/
非同期でガンガン全文検索エンジンを叩きたいな、ということでAnyEvent::Groonga。
なおYappo さんが取り組まれているCライブラリのperlバインディングスとは異なり、AE::Groongaはgroongaディストリビューションに同梱されてるオリジナルの「groongaサーバ」を対象としています。
このgroongaの組み込みサーバは、じつはhttpとgqtp(groonga独自プロトコルらしい)両方をしゃべれます。また普通にローカルのDBとしての問い合わせもできます。
んで、このgqtpプロトコルとローカルDB問い合わせについては、どちらの場合にもクライアント側にgroongaがインストールされている必要があります。
ですがhttpであればクライアント側にはgroongaは必要ありません。なのでgroongaサーバ以外のマシンからは普通にhttp経由で呼び出すのがお手軽なユースケースかと思われます。
使い方
使い方はこう。
use AnyEvent::Groonga; my $groonga = AnyEvent::Groonga->new( protocol => 'http', host => 'localhost', port => '10041', ); # blocking interface my $result = $groonga->call( select => { table => "Site", query => 'title:@test', output_columns => [qw(_id _score title)], sortby => '_score', } )->recv; print $result->dump;
$any_event_cv = $groonga->call( groongaコマンド => 引数リファンレンス ) という形になります。
AnyEventのcondvarがかえってくるので、そのままrecvすればブロッキング風になります。
ノンブロッキングにする場合はcall backを指定してください。
# non-blocking interface $groonga->call( table_create => { name => "Test", .... } )->cb( sub { $result = $_[0]->recv; } );
なお$resultとして取得したオブジェクトですが、AnyEvent::Groonga::Resultというクラスのインスタンスになっています。
例外としてselectコマンドの時だけAnyEvent::Groonga::Result::Selectというさらに深いネームスペースのオブジェクトを返すようにしています。
selectの時だけ$result->hit_numとか$result->itemsなどのメソッドが使えてちょっと便利、にしたつもりなんですが、どうかな。。自分でももっと使い込んでみないとわからんな。ここら辺の設計はだいぶ甘いかも。
なおgroongaのコマンドは全部で20種類以上あり、一応その全部に対してAnyEvent経由でコマンドを投げられるはずなんですが、まだ検証はたりてません。
元のDSLが少々むずかしくて、とくにJSONパラメータでのクオーテーションのエスケープとか、文字コードまわりとか、泥臭い変換処理を伴うため、まだまだ不十分。バグとか不具合などあったら教えてください。
なおgroongaコマンドの詳細についてはgroongaのオフィシャルサイトのドキュメントを参照して下さい。
AnyEvent::Groongaの使い方は、まだあんまりドキュメント書けてないのでテストコードでも見ながらがんばってみてください。
sennaとgroongaについて
全文検索エンジンと言えばsenna、ということで今まで頑にsenna(正確にはtritonn)だけを愛し続けてきたのですが、やっぱり書き込みが多くなってくるとMyISAMのテーブルロックが頻発し、全体のパフォーマンスが低下するし。。。そろそろお別れかしら、と思い始めていました。
というわけで、そろそろgroonga!
- なんといっても「参照ロックフリー」だゼ
- mysqlやpostgresに依存しない独自のストレージ持ってるゼ
- カラム志向のちょっと頑固なKVSだゼ
もうgroongaがまぶしすぎて困ります。
実際に書き込み処理をループで大量にまわしつつ、同じディスクを読んでいるgroongaサーバにselectを並列して投げてみましたが、ほとんどパフォーマンスは劣化しません。参照ロックフリーってすごくいいかも〜。
mysqlのgroongaストレージエンジンも既にリリースはされていますが、
結論として、groongaオリジナルサーバでも十分にパフォーマンスよさげなので、AnyEvent::Groongaは手っ取り早くgroongaの恩恵にあずかりたい、とう人におすすめです。