RedisのHyperLogLogを試してみる
AWSのElasticCacheのredisが2.8.19になりHyperLogLogというのをサポートしたとのことなので、どんなものか試してみました。 HyperLogLogの利用法としてユニークユーザの推移に便利と記事でよく紹介されているようで、 今回のお試しでもwebサイトに訪問した人のユニークユーザが大体どのくらいかを簡単にわかるようにしてみます。
HyperLogLogについてはこちらの記事が参考になりました。
nginxのインストール
webサイトはnginxでサービスするものとして、nginxの中でredisのコマンド叩くことになるのでredis2-nginx-moduleやらを追加してngxinのrpmを作成します。
wget http://nginx.org/packages/rhel/6/SRPMS/nginx-1.6.2-1.el6.ngx.src.rpm rpm -ivh nginx-1.6.2-1.el6.ngx.src.rpm git clone https://github.com/openresty/redis2-nginx-module.git git clone https://github.com/vkholodkov/nginx-eval-module.git git clone https://github.com/simpl/ngx_devel_kit.git git clone https://github.com/openresty/set-misc-nginx-module.git
nginx.specのconfigureのところに下記追加
--add-module=~/src/redis2-nginx-module \ --add-module=~/nginx-eval-module \ --add-module=~/ngx_devel_kit \ --add-module=~/set-misc-nginx-module \
ビルドしてインストール
rpmbuild -bb nginx.spec rpm -ivh RPMS/x86_64/nginx-1.6.2-1.amzn1.ngx.x86_64.rpm
nginxの設定
location内のredis2_queryでpfaddを叩きます。 セッションの中に含まれてるユーザIDなどをキーにしてredisに渡せばユニークユーザ数を推移ができるのですが、 今回はリクエストの度にnginx内でユーザID相当なものをランダムで生成します。 そして、このidをredisのpfaddコマンドでuuというHyperLogLogデータに追加していきます。
upstream staging-redis { server redisサーバのIP:6379 fail_timeout=0; keepalive 1024; } location / { eval $ret { set_random $uid 1 1000000000; redis2_query select 1; redis2_query pfadd uu $uid; redis2_pass staging-redis; } ... }
テスト
- pfcountでuuの異なり数を確認する(異なり数=ユニークユーザ数と判断する)
redis-cli > pfcount uu (integer) 0
- 10000回ほどアクセスしてみる
ab -c 100 -n 10000 http://staging/test.html
- もう1回pfcountで確認
redis-cli >pfcount uu (integer) 9998
pfcountは推定なので実際のアクセス数と同じにはなりません。 そもそもuidがランダム生成なので重複したuidが作られてるかもしれません。
パフォーマンス
redisのpfaddのパフォーマンスがどのくらいかをsetの場合とで単純に比べてみました。 上記のabのスループット結果です。特に違いがないようです。
- pfaddの場合
Requests per second: 4322.10 [#/sec] (mean) Time per request: 23.137 [ms] (mean)
- setの場合
Requests per second: 4138.47 [#/sec] (mean) Time per request: 24.164 [ms] (mean)