Redisでランキングを作る
「Redisでランキングを作る」という手垢の付きまくったネタをPerlでやります。 Redis::Clientを使いました。
データの準備
Redisサーバーをインストール・起動した後、ランキング用のデータを準備します。 100万件のデータをスクリプトで入れました。 1件1件いれていくと時間がかかるので、1000件まとめて1000回入れました。
init.pl
#!/usr/bin/perl use strict; use warnings; use Redis::Client; my $redis = Redis::Client->new; foreach my $repeat (1 .. 1000) { my @data = map { my $score = int rand (1000000); my $num = ($repeat - 1) * 1000 + $_; +( $score => $num ); } ( 1 .. 1000 ); $redis->zadd( 'ranking', @data ); }
zaddメソッドでソート済みセットを作っています。 データを入れるときは、$redis->zadd( ソート済みセット名, score, id)の形で入れます。 score, idの組は1度に複数入れることができます。
ランキングの取得
sample.pl
#!/usr/bin/perl use strict; use warnings; use Redis::Client; my $redis = Redis::Client->new; my $count = $redis->zcard('ranking'); print "count: $count\n"; my @result = $redis->zrange('ranking', $count - 3, $count - 1); foreach my $num (@result) { print join ',', ($num, $count - $redis->zrank('ranking', $num), $redis->zscore('ranking', $num)); print "\n"; }
投入済みデータからランキングを作ります。
zcardメソッドはソート済みセットが保持するデータ数を返します。
zrangeメソッドではソート済みセットから指定した範囲のデータを取得します。 $redis->zrange('ranking', n, m)のように呼べば、rankingという名前のソート済みセットでscoreで昇順に並べられたデータの中からn番目からm番目のデータを取得します。 n, mに負の値を指定すると、最後尾から1,2,…の用に逆から取り出していきます。 scoreの上位3件が欲しいので、$count -3 , $count - 1と指定してますが、-3, -1も同じです。
zrankでは昇順に並んだランキング内の順位を返します。同率などは考慮しません。 zrevrankを使うと降順に並んだランキング内の順位を返します。
zscoreは実際にランキングの基となるscoreを返します。