インフラブログ

とあるWEBサイトのインフラを構築運用するメモ

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)