非同期で全文検索エンジン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の恩恵にあずかりたい、とう人におすすめです。