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を返します。