memcachedのように使えるBloomFilter
YAPCでmalaさんの話を聞いていて、memcachedのようにお手軽に使えるbloom filterがあるとひょっとすると便利かもしれない、とふと思ったのでAnyEventつかって、Bloom::Fasterのwrapperを書いてみました。
https://github.com/walf443/p5-bloomd-server
以下のようなプログラムを書いてサーバーを起動します
use strict; use warnings; use EV; use AnyEvent; use Bloomd::Server my $cv = AnyEvent->condvar; my $server = Bloomd::Server->new( capacity => 100_000_000, backupdir => '.', ulog => 'ulog', ); $server->run $cv->recv;
起動したらncで会話できます。
$ echo "check foo" | nc localhost 26006 CHECK foo 0 END $ echo "check foo barfoo" | nc localhost 26006 CHECK foo 0 CHECK barfoo 0 END $ echo "set foo" | nc localhost 26006 OK $ echo "check foo barfoo" | nc localhost 26006 CHECK foo 1 CHECK barfoo 0 END
statsでサーバーの統計情報を知ることができます。
$ echo "stats" | nc localhost 26006 STAT capacity 100000000 STAT cmd_check 6 STAT cmd_set 1 STAT error_rate 0.001 STAT pid 87719 STAT server_id 1 STAT server_time 132001511179202 STAT uptime 237 STAT key_count 2970 STAT vector_size 1155555563 END
backupコマンドを実行すると、backupdirで指定したディレクトリに、snapshot + timestampというファイル名でbackupを取ることができます。
snapshot.132001522548775
backupするコマンドがXSレベルでファイルの読みかきをしているので、AnyEventをブロックしてしまうという問題は、redisをパクって、forkして子プロセスでバックアップファイルを作ることで解決しました。
from_snapshotでファイル名を指定すると、バックアップを使って、起動することができます。
また、レプリケーションをすることができます。
欠点としては、あまり早くないので、基本的には他にある既存のKVSを使った方がよいケースが多いでしょう。ただ、データをどれだけsetしても使用メモリ等は増えていかないので、そういう面で運用しやすさはあるのかなーと思っています。
今自分が使えそうかなーと思っているユースケースとしては、色々なユニークユーザーの件数の集計処理をリアルタイムで実現するのに使えるかもな、という感じです。(ユニークユーザーのデータを保持しようとするとたくさんのデータを保存しないといけないが、具体的なユーザーはわからなくてよく、だいたいのユニークがわかればよい)